diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c6c3eeb193b462d13cc1c9c97752290f3086b6cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,74 @@ +# General +.pytest_cache +.DS_Store +.AppleDouble +.LSOverride +__pycache__ +*.pyc +client_ref/ +_store/ +.cache/ +client_ref +*.swp +raw_data + +# Icon must end with two \r +Icon + +# Package files +*.egg-info + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +.idea +.vscode + +.ipynb_checkpoints +client/src/node_modules +client/src/.cache-loader + +# HDF5 and faiss files can be too big for git +*.hdf5 +*.faiss +*.code-workspace + +# Datasets +data/*/wizard-of-oz.txt +wizard-of-oz.txt +data/*/wikipedia*.csv.gz +*_tst +server/data/*.zip +allResponses.json +*.h5py +*.pckl + +# Dev notebooks +notebooks/*.ipynb + +# Demo +client/src/demo + +# Mypy static checking +.mypy_cache +.pytest_cache + +# Emacs things +\#* +.#* \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5888cb1e6224570e6ee795024f6493460b7ac9f9 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +ENV_NAME="exbert" + +env: + conda env create -f ./environment.yml; \ + conda activate $(ENV_NAME); \ + pip install -e server/spacyface; \ + pip install -e server/transformers; \ + pip install -e server; \ diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ddf7779fdeb05a47b4f4353d7ade9fa654d61f7b --- /dev/null +++ b/README.md @@ -0,0 +1,217 @@ +# exBERT + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + + +### A Visual Analysis Tool to Explore Learned Representations in Transformers Models +by Ben Hoover, Hendrik Strobelt, Sebastian Gehrmann
+from IBM Research and Harvard NLP + +Link to pre-paper and demo: [exbert.net](http://exbert.net) + + +
+ + + +
An overview of the different components of the tool. The token ``escape'' is selected and masked at 0-[all]. The results from a corpus search by token embedding are shown and summarized in (d-g). Users can enter a sentence in (a) and modify the attention view through selections in (b). Self attention is displayed in (c). The blue matrices show the attention of a head (column) to a token (row). Tokens and heads that are selected in (c) can be searched over the annotated corpus (shown: Wizard of Oz) with results presented in (d). Every token in (d) displays its linguistic metadata on hover. A colored summary of the matched token (black highlight) and its context is shown in (e), which can be expanded or collapsed with the buttons above it. The histograms in (f) and (g) summarize the metadata of the results in (d) for the matched token and the token of max attention, respectively.
+ +
+ +### Version 0.9 + +- [Overview](#overview) +- [Components](#components) +- [Install and Getting Started](#install-and-getting-started) +- [Development](#development) + + + + + +## Overview + +exBERT is a tool that enables users to explore what and how transformers learn to model languages. The tool comes equipped with a pretrained base version of BERT, a state of the art architecture based on transformers. To explore what this architecture has learned, you can input any sentence to the model and the tool will parse the sentence into tokens suitable for BERT (using the BPE tokenizer) and pass these tokens through the model. The attentions and ensuing word embeddings of each encoder are then extracted and displayed for interaction. + +To ease interpretability of language features, several key features of BERT have been disabled: + +1. The attentions toward [CLS] and [SEP] tokens have been zeroed. The [CLS] token is typically useful in classification tasks where the entire sentence needs to have an embedding to summarize it, and the [SEP] has been shown to be a no-op for heads that haven't learned anything. +2. BERT is able to concatenate two sections of text for training (separated by the [SEP] token mentioned above), and attention patterns can be learned between the two sentences. This enables BERT to apply to a wide range of applications. However, the intention of this tool is to focus on self-attention - that is, the attention of the words in a sentence to other words in the same sentence - and the functionality to look at attention between different words has been dropped. + +Even though BERT is able to analyze large chunks of paragraph at once, this tool primarily focuses on language features within one sentence and thus only searches across a corpus that has been split by sentence. + +Importantly, BERT's ability to mask particular tokens (by using the [MASK] token in place of the original token) has been preserved. + +## Components + +![components](client/src/img/annotated_instructions2.png) + + +### 1) The Attention Explorer + + +#### 1a) Sentence Input + +Type in any english sentence you want to analyze in the ensuing visualization. Just note that the longer the sentence, the longer the visualization will require to initialize. + + +#### 1b) Threshold Slider + +The Threshold Slider is used to control how much attention is displayed in the main attention graph. For each word, show the largest attentions until X amount of the total attention has been displayed. At 1, all the attention connections are shown. At 0, nothing is shown. Use this if you are only interested in seeing what each word is most interested in. + + +#### 1c) Layer Selection + +Choose the layer of BERT to analyze + + +#### 1d) Head Selector + +Display the selected heads, with the option to select all or none. For convenience, interaction has been added to the Attention Summary Boxes that allows you to select or deselect heads from the visualization itself. + + +#### 1e) Attention Summary Boxes + +Every row represents the total attention to a token, and every column represents a different head. By looking down a column, you can see how strongly any particular head is activated at a particular head/layer. By hovering over any column, you can see that attentions that belong to just that head in the main graph. By selecting a column, you can select or deselect that head. This will both remove the effect of that head on the overall visualization and indicate which heads you are interested in searching over in the corpus. + +The left side indicates how much total attention each head is going out of each word. The right side indicates the total attention from each head going into each word. + + +#### 1f) Attention Graph + +This central display shows how tokens attend to other tokens in the same sentence. By hovering over any token, you can see only the attentions going into or out of that particular word. By single clicking on it, you can freeze the view of that particular token and explore how the heads interact with only that token's attention. This also indicates which embedding / headlist you are interested in searching the corpus for. By double clicking on the token, you can mask that token, which passes all the tokens back to BERT with the [MASK] token replacing the token you just double clicked. This often changes quite a few of the attentions and will rerender the attention graph. You can then continue to explore the attentions and select tokens and head as usual. + + +### 2) Corpus Explorer + +Right now, the only available corpus to search is the Wizard of Oz (WoZ). This corpus has been split into sentences, parsed for language features such as part of speech (POS), dependency (DEP), and entity information using SPACY, merged into the BERT tokenization scheme, stored into an HDF5 file, and indexed by FAISS for quick lookup. This same procedure will need to be applied to other corpora to be searched. + + +#### 2a) Search Buttons: + +There are two buttons to perform a search of the available corpus: Search by Head and Search by Embedding. + +To search by embedding, the embedding of the selected token and the layer at which to compare embeddings are passed to the backend. The processed corpus is searched for the words that are nearest to the embedding (by inner product search) at that particular layer and displayed in the Corpus Explorer. + +To search by head, the selected layer, the selected heads, and the concatenated head vector for the selected token are passed to the backend. The head vector is then set to 0 at all indices that are from one of the unselected heads. This vector is then searched across the corpus by inner product. + +Note that the term "inner product" is used. Since the embeddings and the head vectors are normalized, this is equivalent to performing a cosine-similarity search. + + +#### 2b) Histogram Information + +There are two different histograms of information that are displayed: the Metadata histogram (in purple) and the positional histogram (in black). By selecting the dropdown underneath the Metadata histogram, you can change the displayed matrix in the Corpus controller. + + +#### 2c) Corpus Metadata Matrix control buttons + +The control buttons allow you to see a certain amount of context on either side of the matched word. The arrows add context one word to the left or right, whereas the red X deletes a context from the left or right. The blue refresh symbol is used to adjust the heights of each cell to correspond to the height of it's sentence, which is important when the browser window has been resized in some way. + + +#### 2d) Corpus Metadata Matrix + +The metadata matrix is an array of colors that summarize the metadata information of the corresponding sentence to its right. By hovering over any cell, you will be able to see what that particular color represents. There are unfortunately too many values for POS and DEP to give each a unique color that is distinct from all other colors, so some colors may overlap. Black cells indicate that you have reached a sentence boundary. + + +#### 2e) Corpus Explorer + +This display shows all words most closely matching the selected token / layer / head information indicated in the Attention Explorer. Matched words have a thick red border. Hovering over any word will give you its POS and DEP information, the amount of attention the matched word is paying to that word, and will read ENTITY if that word was determined to be an entity in the original corpus. + +## Install and Getting Started + +Note: This code has possible OS dependencies as it was developed exclusively on MacOS. + +### Setting up the Environment +1. From the root of this project, create a new conda directory with `conda env create -f environment.yml`. This will create an environment named `exbert`. +2. Activate this environment with `conda activate exbert`. At this point, if you want to install the development dependencies, you can do so with `conda env update -f environment-dev.yml` +3. You will need to install spacy's `en_core_web_sm` as well. To do this, run: `python -m spacy download en_core_web_sm` + + +### Generating Example Data + +please see the [instructions here](https://github.com/bhoov/exbert/tree/master/server/data_processing) + + +### Running Locally +Starting the backend: + +```bash +conda activate exbert +python server/main.py +``` + +### Notes on setting up conda +If setting up conda for the first time, we recommend downloading Miniconda with the following curl command: + +``` +curl 'https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh' +``` + +Promptly refresh your shell environment and run `conda update conda` to be able to install from the `conda env create` command above. + + +## Development + +If you want to make custom changes to the code, these are some hints to get you started. + +### Use as package +Some find it useful to expose the code inside `server` for development in an environment like Jupyter Notebooks. From the root folder with the `exbert` environment active: + +```bash +conda env update -f environment-dev.yml +pip install -e ./server +``` + +Now the `exbert` environment should allow the server code to be accessible in any folder so long as there are no additional module name clashes in the environment. + +### Compiling the frontend + +```bash +cd client/src +npm install #installs all necessary node packages +npm run build #This will create the static files living in `client/dist`. +``` + +## Running a development environment +You can run a client server that automatically recompiles the frontend with `npm run ww`. After making a change, you should be able to refresh the browser window to see your most recent changes. + +Because the backend has to load in a lot of data for inference, we do not allow auto-backend refresh on every saved change in flask even though the framework supports it. + +### Uploading your own model locally +Uploading your own model consists of the following steps: + +1. *Save your pretrained huggingface model* according to the naming conventions specified in the "modeling_auto.py" of the original transformers repo: + +``` +The model class to instantiate is selected as the first pattern matching + in the `pretrained_model_name_or_path` string (in the following order): + - contains `t5`: T5Model (T5 model) + - contains `distilbert`: DistilBertModel (DistilBERT model) + - contains `albert`: AlbertModel (ALBERT model) + - contains `camembert`: CamembertModel (CamemBERT model) + - contains `xlm-roberta`: XLMRobertaModel (XLM-RoBERTa model) + - contains `roberta`: RobertaModel (RoBERTa model) + - contains `bert`: BertModel (Bert model) + - contains `openai-gpt`: OpenAIGPTModel (OpenAI GPT model) + - contains `gpt2`: GPT2Model (OpenAI GPT-2 model) + - contains `transfo-xl`: TransfoXLModel (Transformer-XL model) + - contains `xlnet`: XLNetModel (XLNet model) + - contains `xlm`: XLMModel (XLM model) + - contains `ctrl`: CTRLModel (Salesforce CTRL model) +``` + +Right now, only BERT, RoBERTa, GPT2, and DistilBERT are supported for context searching. You can use the rest without the context searching as desired. + +2. *Create the reference corpus*. **Warning**: Depending on the number of layers and size of the hidden dimension in the model, this step could take many gigabytes on your computer to store the hidden representations and attentions at every layer. + +## Notes on SubRepo Usage +This project makes use of two public pip repositories (`transformers` and `spacyface`), both of which needed modification as this project was being developed. The `git-subrepo` tool was used to achieve this workflow with a forked repository of both transformers and spacyface. However, this introduces the following steps when setting up the environment: + +1. From the `transformers/` directory, run `pip install -e .` +2. Repeat for the `spacyface/` directory. + +## Acknowledgements +This project was inspired in part by the original [BertViz by Jesse Vig](https://github.com/jessevig/bertviz). + +## Debugging +- If you get a `No module named '_swigfaiss'` error, check that `libomp` is installed on your system. If you are on a mac, this is as simple as `brew install libomp`. diff --git a/client/dist/05ca9c06114e79436ea9b5c8d4a7869c.ttf b/client/dist/05ca9c06114e79436ea9b5c8d4a7869c.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4a890111a095b61af17e2ca4239254a6347803d6 Binary files /dev/null and b/client/dist/05ca9c06114e79436ea9b5c8d4a7869c.ttf differ diff --git a/client/dist/4171e41154ba857f85c536f167d581ba.ttf b/client/dist/4171e41154ba857f85c536f167d581ba.ttf new file mode 100644 index 0000000000000000000000000000000000000000..031c5ad54de2af6b5a3950b923f2bd0fb2463c4f Binary files /dev/null and b/client/dist/4171e41154ba857f85c536f167d581ba.ttf differ diff --git a/client/dist/7eeb10384e8e1ef96c87f7074cf2ef59.ttf b/client/dist/7eeb10384e8e1ef96c87f7074cf2ef59.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ce42e55bafd813315a35dbb44fd0564ad6e95a20 Binary files /dev/null and b/client/dist/7eeb10384e8e1ef96c87f7074cf2ef59.ttf differ diff --git a/client/dist/a849e7649e2005ab4aecfa50d96120e1.ttf b/client/dist/a849e7649e2005ab4aecfa50d96120e1.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4b9c15f0134a75362a474749aa6e1878b1df87cd Binary files /dev/null and b/client/dist/a849e7649e2005ab4aecfa50d96120e1.ttf differ diff --git a/client/dist/exBERT.html b/client/dist/exBERT.html new file mode 100644 index 0000000000000000000000000000000000000000..081db10e82a7598e4a33a4c406635de2594eab6d --- /dev/null +++ b/client/dist/exBERT.html @@ -0,0 +1,226 @@ + + + + + + + + + exBERT + + + + + + + + +
+
+ +
+ +
+
+
+ +

+
+
+ +
+
+
+ +
+ +
+
+
+ + +
+
+
+ +
+
+
+ +
+
+ Layer: +
+ +
+
+
+
+ Hide Special Tokens +
+ + +
+
+ +
+
+
+ Selected heads: +
+
+
+ +
+ + +
+ +
+

You focus on one token by click.
+ You can mask any token by double click.

+

You can select and de-select a head by a click on the heatmap columns

+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+ +
+ +
+ + +
+ +
+
+ + Search +
+
+ +
+
+ + +
+
+ +
+
+ +
+ Matched Word Summary: +
+ + + +
+
+
+ +
+ +
+ Max Attention Summary: + +
+ + + + +
+ +
+
+
+
+ +
+ +
+ + +
+
+
+ + + ←||→ + + + +
+ + +
+
+
+
+
+
+
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/client/dist/img/annotated_instructions2.png b/client/dist/img/annotated_instructions2.png new file mode 100644 index 0000000000000000000000000000000000000000..dc5f9b966e2782404b314f0b7aa81cd570498523 Binary files /dev/null and b/client/dist/img/annotated_instructions2.png differ diff --git a/client/dist/img/exBERT.png b/client/dist/img/exBERT.png new file mode 100644 index 0000000000000000000000000000000000000000..c17abeb6127a67055063b0d1c8c0b781b6ef0bb3 Binary files /dev/null and b/client/dist/img/exBERT.png differ diff --git a/client/dist/img/exBERT.svg b/client/dist/img/exBERT.svg new file mode 100644 index 0000000000000000000000000000000000000000..52bcc8c1077f25792d463d0c3064c2d35ae1b850 --- /dev/null +++ b/client/dist/img/exBERT.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/client/dist/img/exBERT_favicon.png b/client/dist/img/exBERT_favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..d1f5d36ce1637f06da8f7656bdd62316852c63d2 Binary files /dev/null and b/client/dist/img/exBERT_favicon.png differ diff --git a/client/dist/img/exBERT_overview.png b/client/dist/img/exBERT_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d99cfa71ced20abbbaa0cc9451966e21bd5141 Binary files /dev/null and b/client/dist/img/exBERT_overview.png differ diff --git a/client/dist/img/exbert_teaser_V2.png b/client/dist/img/exbert_teaser_V2.png new file mode 100644 index 0000000000000000000000000000000000000000..7f843c6e48fb796f23f2aa0d05b8c4adc43873b8 Binary files /dev/null and b/client/dist/img/exbert_teaser_V2.png differ diff --git a/client/dist/img/favicon.png b/client/dist/img/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7285a46f9dc7edcd6259c8207c3ebcf0800c20bd Binary files /dev/null and b/client/dist/img/favicon.png differ diff --git a/client/dist/img/harvardnlp_logo.png b/client/dist/img/harvardnlp_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..eb57f712b25cebf46174e22e998ab8b393476f57 Binary files /dev/null and b/client/dist/img/harvardnlp_logo.png differ diff --git a/client/dist/index.html b/client/dist/index.html new file mode 100644 index 0000000000000000000000000000000000000000..03774870d641820df4af9e12ac9d8a20bd8d4380 --- /dev/null +++ b/client/dist/index.html @@ -0,0 +1,236 @@ + + + + + + + + + exBERT + + + + + + + + + + + + + + + +
+ + +

+ Large language models can produce powerful contextual representations that lead to improvements across many + NLP tasks. + Since these models are typically guided by a sequence of learned self attention mechanisms and may comprise + undesired inductive biases, it is paramount to be able to explore what the attention has learned. + While static analyses of these models lead to targeted insights, interactive tools are more dynamic and can + help humans better gain an intuition for the model-internal reasoning process. +

+ +

+ We present exBERT , an interactive tool named after the popular BERT language model, that provides + insights into the meaning of the contextual representations by matching a human-specified input to similar + contexts in a large annotated dataset. + By aggregating the annotations of the matching similar contexts, exBERT helps intuitively explain + what each attention-head has learned. +

+ +

Large language models can produce powerful contextual representations that lead to improvements across many + NLP tasks. Though these models can comprise undesired inductive biases, it is challenging to identify what + information they encode in their learned representations.

+ +

Since the model-internal reasoning process is often guided by a sequence of learned self-attention + mechanisms, it is paramount to be able to explore what the attention has learned. While static analyses for + this can lead to targeted insights, interactive tools can be more dynamic and help humans gain an intuition + for the model-internal reasoning process. We present exBERT, a tool that helps to gain insights into the + meaning of the contextual representations. exBERT matches a human-specified input to similar contexts in a + large annotated dataset. By aggregating these annotations across all similar contexts, exBERT can help to + explain what each attention-head has learned.

+ +

Thanks to + Jesse Vig + for feedback. Please let us know what you think by commenting below!

+ +
+ + +
+
+ + + +
+ + +
+ + +
+
+
+ Tool screenshot +
+
+
+ +
+ +
+
+ + + +
+ + +
+ + +
+ +
+
+

+

We care about your privacy, but know that your activity on the site may be monitored. For more + information, check out the links below.

+
+
+ +
+ +
+ + +
+ +
+ +
+ IBM Research, Cambridge
+ MIT-IBM Watson AI Lab +
+
+ +
+
+ + + + + +
+ + + +
+ + + + + + \ No newline at end of file diff --git a/client/dist/main.css b/client/dist/main.css new file mode 100644 index 0000000000000000000000000000000000000000..76d4e316422d5253a7156ae7be9b779de8153e5f --- /dev/null +++ b/client/dist/main.css @@ -0,0 +1,4 @@ +@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:300;src:local("IBM Plex Sans Light"),local("IBMPlexSans-Light"),url(7eeb10384e8e1ef96c87f7074cf2ef59.ttf) format("truetype")}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:400;src:local("IBM Plex Sans Regular"),local("IBMPlexSans-Regular"),url(05ca9c06114e79436ea9b5c8d4a7869c.ttf) format("truetype")}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:600;src:local("IBM Plex Sans SemiBold"),local("IBMPlexSans-SemiBold"),url(a849e7649e2005ab4aecfa50d96120e1.ttf) format("truetype")}@font-face{font-family:IBM Plex Sans;font-style:normal;font-weight:700;src:local("IBM Plex Sans Bold"),local("IBMPlexSans-Bold"),url(4171e41154ba857f85c536f167d581ba.ttf) format("truetype")} +body{background-color:#fff;font-family:IBM Plex Sans,sans-serif;font-weight:400}.sticky{position:fixed}.noscroll{overflow:hidden}.vpartial{max-height:90vh}.scrolling{overflow:auto;max-height:98%}.btn .btn-xs{padding:.25rem .4rem;font-size:.875rem;line-height:.5;border-radius:.2rem}button{-webkit-transition-duration:.4s;transition-duration:.4s;background:transparent;padding:5px;border-radius:5px;background-color:#d3d3d3}button.selected,button:active :focus{background-color:#98b7d9}#loader{border:5px solid #f3f3f3;border-radius:50%;border-top:5px solid #3498db;width:100px;height:100px;-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite;position:absolute;left:50%;top:20%;display:none}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}svg{vertical-align:top}select{font-size:9pt;font-weight:600;background-color:transparent;padding:8px 6px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-radius:4px;border:0;outline:0}.navbar{position:absolute;top:0;left:0;width:100%;height:50px;background-color:#faebd7}.navbarContent{margin:10px 20px}.navbarContent span{padding-left:10px}.navbarContent button{margin-left:10px}.navbarTitle{font-size:12pt;font-weight:700}.main_frame{position:fixed;top:55px;overflow-x:hidden;overflow-y:auto}.floating_content{padding:10px;height:94%}.container{width:100%;height:95%;text-align:center;display:inline-block;margin:5px auto}#bottom-margin{height:100px}.content{max-width:960px;margin:auto}.whitespace{height:8vh}#sentence-input{margin-bottom:-30px;margin-right:-30px;margin-left:10px;width:90%}#sentence-input form{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-evenly;align-items:center}#sentence-input form .form-group{flex-grow:3}#sentence-input form .form-group input{width:100%;margin-right:5%}#sentence-input form .padding{flex-grow:0.3}#sentence-input form .btn{flex-grow:1}.input-description{font-weight:800}.connector-controls{display:grid;grid-template-columns:.5fr .5fr}.slide-container{grid-column-start:1;grid-column-end:2;grid-row-start:1;grid-row-end:2;margin:auto;text-align:center;width:75%}.slider{-webkit-appearance:none;width:10px;height:10px;border-radius:5px;background:#d3d3d3;outline:none;opacity:.7;-webkit-transition:.2s;transition:opacity .2s}.slider:hover{opacity:1}.slider::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:15px;height:15px;border-radius:50%;background:#666;cursor:pointer}#layer-selection{grid-column-start:1;grid-column-end:2;grid-row-start:2;grid-row-end:3}.layer-select{margin-bottom:2em}#atn-container{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:center;align-items:top;margin:0 auto;width:100%;vertical-align:top}#atn-container #left-att-heads{order:1;display:inline-block;vertical-align:top}#atn-container #left-tokens{order:2;text-align:right;vertical-align:top}#atn-container #atn-display{order:3;vertical-align:top}#atn-container #right-tokens{order:4;text-align:left;vertical-align:top}#atn-container #right-att-heads{order:5;vertical-align:top}.att-rect{transition:fill .1s}.token{display:block}.atn-curve{fill:none;stroke:purple}.masked-token{color:rgba(0,0,0,.2)}.unselected{fill:gray}.selected-token{border:3px solid #99c400}.switch{position:relative;display:inline-block;width:60px;height:34px}.switch input{opacity:0;width:0;height:0}.short-slider{cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc}.short-slider,.short-slider:before{position:absolute;-webkit-transition:.4s;transition:.4s}.short-slider:before{content:"";height:26px;width:26px;left:4px;bottom:4px;background-color:#fff}input:checked+.short-slider{background-color:#2196f3}input:focus+.short-slider{box-shadow:0 0 1px #2196f3}input:checked+.short-slider:before{-webkit-transform:translateX(26px);-ms-transform:translateX(26px);transform:translateX(26px)}.short-slider.round{border-radius:34px}.short-slider.round:before{border-radius:50%}#select-all-heads{margin-top:20px;margin-bottom:20px}#corpus-vis{margin:0 auto}#corpus-vis #main-corpus-vis{display:-webkit-flex;display:flex}#corpus-vis #main-corpus-vis #corpus-mat-container{-webkit-flex:initial;flex:initial;vertical-align:top;float:left}#corpus-vis #main-corpus-vis #corpus-mat-container .corpus-mat{display:inline-block;margin-right:.05em;margin-left:.05em}#corpus-vis #main-corpus-vis #corpus-mat-container .offset-0{border:.2em solid #000}#corpus-vis #main-corpus-vis #corpus-mat-container .mat-hover-display{pointer-events:none;display:flex;position:absolute;visibility:hidden;background-color:#c8c8c8;border-radius:8px 8px 1px 8px;margin:auto}#corpus-vis #main-corpus-vis #corpus-mat-container .mat-hover-display p{margin:auto}#corpus-vis #main-corpus-vis #corpus-similar-sentences-div{-webkit-flex:1;flex:1;vertical-align:top;float:left;max-width:80%;max-height:100%}#corpus-vis #main-corpus-vis #corpus-similar-sentences-div .hovered-col{color:orange}#corpus-vis .btn{margin-left:.25em}#corpus-vis .inspector-row{display:block;margin-left:10px;padding-top:.5em;padding-bottom:.5em}#corpus-vis .inspector-cell{display:inline-block;margin-right:3px;text-align:left}#corpus-vis .celltooltip{position:relative;display:inline-block;border-bottom:1px dotted #000}#corpus-vis .celltooltip .tooltiptext{visibility:hidden;width:120px;background-color:#000;color:#fff;text-align:center;padding:5px 0;border-radius:6px;position:absolute}#corpus-vis .celltooltip:hover .tooltiptext{width:120px;bottom:100%;left:50%;margin-left:-60px;visibility:visible}#corpus-vis .celltooltip .tooltiptext:after{content:" ";position:absolute;top:100%;left:50%;margin-left:-5px;border-width:5px;border-style:solid;border-color:#000 transparent transparent}#corpus-vis .matched-cell{border:3px solid #99c400;border-radius:.4em}#corpus-vis .gray-cell{color:rgba(0,0,0,.35)}#corpus-vis .next-cell{color:rgba(228,1,1,.8);-moz-box-shadow:0 0 3px #ccc;-webkit-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc}#histograms{display:block;max-width:100%}#histograms .histogram{display:inline-block;overflow-x:auto}#histograms div{margin-top:10px}#histograms #max-att-histogram .bar{fill:#000}.pos-selector{margin-bottom:40px}body{font-family:IBM Plex Sans}.layerCheckbox{background-color:#d3d3d3;padding-left:8px;padding-right:8px}.layerCheckbox.active{color:#fff;background-color:#6c7067}.main-grid{width:100%;display:grid;grid-template-columns:.18fr .2fr .2fr .04fr .2fr .2fr .18fr;overflow:auto;max-height:100vh}.left-half{grid-column-start:1;grid-column-end:4;margin-left:10px;margin-right:10px}.vpartial-90{max-height:90vh}.vpartial-95{max-height:95vh}.right-half{grid-column-start:5;grid-column-end:9;max-height:98vh}.vertical-separator{border-left:thick solid #42222298;margin:0 auto;margin-top:10px;margin-bottom:10px;border-radius:3px;grid-column-start:4;grid-column-end:5;grid-row-start:1;grid-row-end:5}#vis-break{height:15px}label{margin-left:5px}#header{width:100%;background-color:#d3d3d3;height:40px;margin-bottom:5px}#header .header-logo{height:20px;display:inline-block;margin-left:10px;margin-top:5px;margin-bottom:5px}#header .header-info{font-size:9pt;height:30px;display:inline-block;float:right;margin-right:10px;margin-top:10px}#header #headertext{text-align:center;display:inline-block;font-size:18px;margin-left:30%;margin-top:5px;margin-bottom:5px}.highlighted{background:rgba(152,83,216,.8)}#meta-dropdown,#position-meta-dropdown{margin-bottom:.75em;margin-left:4em}#corpus-control-buttons{margin-bottom:1em;position:fixed relative}#corpus-control-buttons span{margin-left:5px}#selected-heads{margin-bottom:1em}#corpus-selection-description{display:inline-block;margin-right:15px}#corpus-querying,#corpus-querying .btn{display:inline-block}#usage-info{margin-top:10px;color:#575757;font-size:14px}.tick{font-size:18px}#connector-container .mat-hover-display{pointer-events:none;display:block;position:absolute;visibility:hidden;background-color:hsla(0,0%,78%,.93);font-size:14px}#connector-container .mat-hover-display p{margin:4px 1px 1px 4px}.right-token-hover{border-radius:1px 8px 8px 8px;text-align:left}.left-token-hover{border-radius:8px 1px 8px 8px;text-align:right}.next-token{color:rgba(228,1,1,.8);-moz-box-shadow:0 0 3px #ccc;-webkit-box-shadow:0 0 3px #ccc;box-shadow:0 0 3px #ccc} + +/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9mb250cy9wbGV4X3NhbnMuY3NzIiwid2VicGFjazovLy8uL2Nzcy9jc3MvYmFzZS5zY3NzIiwid2VicGFjazovLy8uL2Nzcy9jc3MvU2VudGVuY2VJbnB1dC5zY3NzIiwid2VicGFjazovLy8uL2Nzcy9jc3MvQXR0ZW50aW9uQ29ubmVjdG9yQ29udHJvbHMuc2NzcyIsIndlYnBhY2s6Ly8vLi9jc3MvY3NzL0NvcnB1c1Zpcy5zY3NzIiwid2VicGFjazovLy8uL2Nzcy9jc3MvSGlzdG9ncmFtcy5zY3NzIiwid2VicGFjazovLy8uL2Nzcy9jc3MvbWFpbi5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFdBQ0UsMEJBQ0Esa0JBQ0EsZ0JBQ0EsNEdBQTJILENBRzdILFdBQ0UsMEJBQ0Esa0JBQ0EsZ0JBQ0EsZ0hBQWlJLENBR25JLFdBQ0UsMEJBQ0Esa0JBQ0EsZ0JBQ0Esa0hBQW9JLENBR3RJLFdBQ0UsMEJBQ0Esa0JBQ0EsZ0JBQ0EsMEdBQXdILENBQ3pILGdEO0FDM0JELEtBQ0Usc0JBQ0EscUNBQ0EsZUFBZ0IsQ0FHbEIsUUFDRSxjQUFlLENBR2pCLFVBQ0UsZUFBZ0IsQ0FHbEIsVUFDRSxlQUFnQixDQUdsQixXQUNFLGNBQ0EsY0FBZSxDQUdqQixhQUVJLHFCQUNBLGtCQUNBLGVBQ0EsbUJBQXFCLENBSXpCLE9BQ0UsZ0NBQ0Esd0JBQ0EsdUJBQ0EsWUFDQSxrQkFDQSx3QkFBMkIsQ0FPN0IscUNBQ0Usd0JBQXlCLENBRzNCLFFBQ0UseUJBQ0Esa0JBQ0EsNkJBQ0EsWUFDQSxhQUNBLDBDQUNBLGtDQUNBLGtCQUNBLFNBQ0EsUUFDQSxZQUFhLENBSWYsd0JBQ0UsR0FDRSw4QkFBK0IsQ0FFakMsR0FDRSwrQkFBaUMsRUFJckMsZ0JBQ0UsR0FDRSxzQkFBdUIsQ0FFekIsR0FDRSx1QkFBeUIsRUFJN0IsSUFDRSxrQkFBbUIsQ0FHckIsT0FDRSxjQUNBLGdCQUdBLDZCQUtBLGdCQU1BLDhCQUNBLDJCQUNBLHNCQUNB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LG9CQUNBLGNBQ0Esa0JBQ0Esa0JBQ0Esb0NBQ0EsY0FBZSxDQUtoQiwwQ0FIRyxzQkFBdUIsQ0FNN0IsbUJBQ0ksOEJBQ0EsZUFBZ0IsQ0FHcEIsa0JBQ0ksOEJBQ0EsZ0JBQWlCLENBR3JCLFlBQ0UsdUJBQ0EsNkJBQ0EsZ0NBQ0EsdUJBQXdCLEMiLCJmaWxlIjoibWFpbi5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBjeXJpbGxpYy1leHQgKi9cbkBmb250LWZhY2Uge1xuICBmb250LWZhbWlseTogJ0lCTSBQbGV4IFNhbnMnO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtd2VpZ2h0OiAzMDA7XG4gIHNyYzogbG9jYWwoJ0lCTSBQbGV4IFNhbnMgTGlnaHQnKSwgbG9jYWwoJ0lCTVBsZXhTYW5zLUxpZ2h0JyksIHVybChJQk1fUGxleF9TYW5zL0lCTVBsZXhTYW5zLUxpZ2h0LnR0ZikgZm9ybWF0KCd0cnVldHlwZScpO1xufVxuXG5AZm9udC1mYWNlIHtcbiAgZm9udC1mYW1pbHk6ICdJQk0gUGxleCBTYW5zJztcbiAgZm9udC1zdHlsZTogbm9ybWFsO1xuICBmb250LXdlaWdodDogNDAwO1xuICBzcmM6IGxvY2FsKCdJQk0gUGxleCBTYW5zIFJlZ3VsYXInKSwgbG9jYWwoJ0lCTVBsZXhTYW5zLVJlZ3VsYXInKSwgdXJsKElCTV9QbGV4X1NhbnMvSUJNUGxleFNhbnMtUmVndWxhci50dGYpIGZvcm1hdCgndHJ1ZXR5cGUnKTtcbn1cblxuQGZvbnQtZmFjZSB7XG4gIGZvbnQtZmFtaWx5OiAnSUJNIFBsZXggU2Fucyc7XG4gIGZvbnQtc3R5bGU6IG5vcm1hbDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgc3JjOiBsb2NhbCgnSUJNIFBsZXggU2FucyBTZW1pQm9sZCcpLCBsb2NhbCgnSUJNUGxleFNhbnMtU2VtaUJvbGQnKSwgdXJsKElCTV9QbGV4X1NhbnMvSUJNUGxleFNhbnMtU2VtaUJvbGQudHRmKSBmb3JtYXQoJ3RydWV0eXBlJyk7XG59XG5cbkBmb250LWZhY2Uge1xuICBmb250LWZhbWlseTogJ0lCTSBQbGV4IFNhbnMnO1xuICBmb250LXN0eWxlOiBub3JtYWw7XG4gIGZvbnQtd2VpZ2h0OiA3MDA7XG4gIHNyYzogbG9jYWwoJ0lCTSBQbGV4IFNhbnMgQm9sZCcpLCBsb2NhbCgnSUJNUGxleFNhbnMtQm9sZCcpLCB1cmwoSUJNX1BsZXhfU2Fucy9JQk1QbGV4U2Fucy1Cb2xkLnR0ZikgZm9ybWF0KCd0cnVldHlwZScpO1xufVxuIiwiYm9keSB7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYigyNTUsIDI1NSwgMjU1KTtcbiAgZm9udC1mYW1pbHk6ICdJQk0gUGxleCBTYW5zJywgc2Fucy1zZXJpZjtcbiAgZm9udC13ZWlnaHQ6IDQwMDtcbn1cblxuLnN0aWNreSB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbn1cblxuLm5vc2Nyb2xsIHtcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnZwYXJ0aWFsIHtcbiAgbWF4LWhlaWdodDogOTB2aDtcbn1cblxuLnNjcm9sbGluZyB7XG4gIG92ZXJmbG93OiBhdXRvO1xuICBtYXgtaGVpZ2h0OiA5OCU7XG59XG5cbi5idG4ge1xuICAuYnRuLXhzIHtcbiAgICBwYWRkaW5nICA6IC4yNXJlbSAuNHJlbTtcbiAgICBmb250LXNpemUgIDogLjg3NXJlbTtcbiAgICBsaW5lLWhlaWdodCAgOiAuNTtcbiAgICBib3JkZXItcmFkaXVzIDogLjJyZW07XG4gIH1cbn1cblxuYnV0dG9uIHtcbiAgLXdlYmtpdC10cmFuc2l0aW9uLWR1cmF0aW9uOiAwLjRzOyAvKiBTYWZhcmkgKi9cbiAgdHJhbnNpdGlvbi1kdXJhdGlvbjogMC40cztcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gIHBhZGRpbmc6IDVweDtcbiAgYm9yZGVyLXJhZGl1czogNXB4O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiBsaWdodGdyYXk7XG5cbiAgJi5zZWxlY3RlZCB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzk4YjdkOTtcbiAgfVxufVxuXG5idXR0b246YWN0aXZlIDpmb2N1cyB7XG4gIGJhY2tncm91bmQtY29sb3I6ICM5OGI3ZDk7XG59XG5cbiNsb2FkZXIge1xuICBib3JkZXI6IDVweCBzb2xpZCAjZjNmM2YzO1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG4gIGJvcmRlci10b3A6IDVweCBzb2xpZCAjMzQ5OGRiO1xuICB3aWR0aDogMTAwcHg7XG4gIGhlaWdodDogMTAwcHg7XG4gIC13ZWJraXQtYW5pbWF0aW9uOiBzcGluIDJzIGxpbmVhciBpbmZpbml0ZTsgLyogU2FmYXJpICovXG4gIGFuaW1hdGlvbjogc3BpbiAycyBsaW5lYXIgaW5maW5pdGU7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogNTAlO1xuICB0b3A6IDIwJTtcbiAgZGlzcGxheTogbm9uZTtcbn1cblxuLyogU2FmYXJpICovXG5ALXdlYmtpdC1rZXlmcmFtZXMgc3BpbiB7XG4gIDAlIHtcbiAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDBkZWcpO1xuICB9XG4gIDEwMCUge1xuICAgIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcbiAgfVxufVxuXG5Aa2V5ZnJhbWVzIHNwaW4ge1xuICAwJSB7XG4gICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7XG4gIH1cbiAgMTAwJSB7XG4gICAgdHJhbnNmb3JtOiByb3RhdGUoMzYwZGVnKTtcbiAgfVxufVxuXG5zdmcge1xuICB2ZXJ0aWNhbC1hbGlnbjogdG9wO1xufVxuXG5zZWxlY3Qge1xuICBmb250LXNpemU6IDlwdDtcbiAgZm9udC13ZWlnaHQ6IDYwMDtcblxuICAvL2JhY2tncm91bmQ6IHVybChcImRhdGE6aW1hZ2Uvc3ZnK3htbDt1dGY4LDxzdmcgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB3aWR0aD0nMTBweCcgaGVpZ2h0PScxMHB4Jz48cG9seWxpbmUgcG9pbnRzPScwLDAgMTAsMCA1LDEwJy8+PC9zdmc+XCIpO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgLy9iYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAvL2JhY2tncm91bmQtcG9zaXRpb246IHJpZ2h0IDVweCB0b3AgOXB4O1xuICAvL2JhY2tncm91bmQtc2l6ZTogN3B4IDdweDtcbiAgLy9wYWRkaW5nOiA1cHggMTVweCA1cHggNXB4O1xuICBwYWRkaW5nOiA4cHggNnB4O1xuICAvL3dpZHRoOiBhdXRvO1xuICAvL2ZvbnQtc2l6ZToxNnB4O1xuICAvL2ZvbnQtd2VpZ2h0OiBib2xkO1xuICAvL3RleHQtYWxpZ246Y2VudGVyO1xuICAvL3RleHQtc2hhZG93OjAgLTFweCAwIHJnYmEoMCwgMCwgMCwgMC4yNSk7XG4gIC13ZWJraXQtYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBib3JkZXItcmFkaXVzOiA0cHg7XG4gIGJvcmRlcjogMDtcbiAgb3V0bGluZTogMDtcbn1cbi5uYXZiYXIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNTBweDtcbiAgYmFja2dyb3VuZC1jb2xvcjogYW50aXF1ZXdoaXRlO1xuICAvL3BhZGRpbmc6IDEwcHggMTBweCAxMHB4IDMwcHg7XG59XG5cbi5uYXZiYXJDb250ZW50IHtcbiAgbWFyZ2luOiAxMHB4IDIwcHg7XG5cbiAgc3BhbiB7XG4gICAgcGFkZGluZy1sZWZ0OiAxMHB4O1xuICB9XG5cbiAgYnV0dG9uIHtcbiAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgfVxufVxuXG4ubmF2YmFyVGl0bGUge1xuICBmb250LXNpemU6IDEycHQ7XG4gIC8vbWFyZ2luOiA1cHQ7XG4gIGZvbnQtd2VpZ2h0OiBib2xkO1xufVxuXG4ubWFpbl9mcmFtZSB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgdG9wOiA1NXB4O1xuICAvL21hcmdpbjogMHB4IDUwcHggMHB4IDUwcHg7XG4gIC8vYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgb3ZlcmZsb3cteDogaGlkZGVuO1xuICBvdmVyZmxvdy15OiBhdXRvO1xufVxuXG4uZmxvYXRpbmdfY29udGVudCB7XG4gIHBhZGRpbmc6IDEwcHg7XG4gIGhlaWdodDogOTQlO1xufVxuXG4uY29udGFpbmVyIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogOTUlO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luOiA1cHggYXV0bztcbn1cblxuI2JvdHRvbS1tYXJnaW4ge1xuICBoZWlnaHQ6IDEwMHB4O1xufVxuXG4uY29udGVudCB7XG4gIG1heC13aWR0aDogOTYwcHg7XG4gIG1hcmdpbjogYXV0bztcbn1cblxuLndoaXRlc3BhY2Uge1xuICBoZWlnaHQ6IDh2aDtcbn0iLCJcbiNzZW50ZW5jZS1pbnB1dCB7XG4gICAgbWFyZ2luLWJvdHRvbTogLTMwcHg7XG4gICAgbWFyZ2luLXJpZ2h0OiAtMzBweDtcbiAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgICB3aWR0aDogOTAlO1xuXG4gICAgZm9ybSB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiByb3c7XG4gICAgICAgIGZsZXgtd3JhcDogbm93cmFwO1xuICAgICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWV2ZW5seTtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcblxuICAgICAgICAuZm9ybS1ncm91cCB7XG4gICAgICAgICAgICBmbGV4LWdyb3c6IDM7XG5cbiAgICAgICAgICAgIGlucHV0IHtcbiAgICAgICAgICAgICAgICAvLyBmbGV4LWdyb3c6IDQ7XG4gICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgICAgICAgbWFyZ2luLXJpZ2h0OiA1JTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLnBhZGRpbmcge1xuICAgICAgICAgICAgZmxleC1ncm93OiAwLjM7XG4gICAgICAgIH1cblxuXG4gICAgICAgIC5idG4ge1xuICAgICAgICAgICAgZmxleC1ncm93OiAxO1xuICAgICAgICAgICAgLy8gZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgICAgICB9XG4gICAgfVxufSIsIi5pbnB1dC1kZXNjcmlwdGlvbiB7XG5cdGZvbnQtd2VpZ2h0OiA4MDBcbn1cblxuLmNvbm5lY3Rvci1jb250cm9scyB7XG5cdGRpc3BsYXk6IGdyaWQ7XG5cdGdyaWQtdGVtcGxhdGUtY29sdW1uczogMC41ZnIgMC41ZnI7XG59XG5cbi5zbGlkZS1jb250YWluZXIge1xuXHRncmlkLWNvbHVtbi1zdGFydDogMTtcblx0Z3JpZC1jb2x1bW4tZW5kOiAyO1xuXHRncmlkLXJvdy1zdGFydDogMTtcblx0Z3JpZC1yb3ctZW5kOiAyO1xuXHRtYXJnaW46IGF1dG87XG5cdHRleHQtYWxpZ246IGNlbnRlcjtcblx0d2lkdGg6IDc1JTsgXG59XG5cbi5zbGlkZXIge1xuXHQtd2Via2l0LWFwcGVhcmFuY2U6IG5vbmU7XG5cdHdpZHRoOiAxMHB4O1xuXHRoZWlnaHQ6IDEwcHg7XG5cdGJvcmRlci1yYWRpdXM6IDVweDtcblx0YmFja2dyb3VuZDogI2QzZDNkMztcblx0b3V0bGluZTogbm9uZTtcblx0b3BhY2l0eTogMC43O1xuXHQtd2Via2l0LXRyYW5zaXRpb246IC4ycztcblx0dHJhbnNpdGlvbjogb3BhY2l0eSAuMnM7XG59XG5cbi5zbGlkZXI6aG92ZXIge1xuXHRvcGFjaXR5OiAxO1xufVxuXG4uc2xpZGVyOjotd2Via2l0LXNsaWRlci10aHVtYiB7XG5cdC13ZWJraXQtYXBwZWFyYW5jZTogbm9uZTtcblx0YXBwZWFyYW5jZTogbm9uZTtcblx0d2lkdGg6IDE1cHg7XG5cdGhlaWdodDogMTVweDtcblx0Ym9yZGVyLXJhZGl1czogNTAlO1xuXHRiYWNrZ3JvdW5kOiAjNjY2NjY2O1xuXHRjdXJzb3I6IHBvaW50ZXI7XG59XG5cbiNsYXllci1zZWxlY3Rpb24ge1xuXHRncmlkLWNvbHVtbi1zdGFydDogMTtcblx0Z3JpZC1jb2x1bW4tZW5kOiAyO1xuXHRncmlkLXJvdy1zdGFydDogMjtcblx0Z3JpZC1yb3ctZW5kOiAzO1xuXG59XG4ubGF5ZXItc2VsZWN0IHtcblx0bWFyZ2luLWJvdHRvbTogMmVtO1xufVxuXG4jYXRuLWNvbnRhaW5lciB7XG5cdGRpc3BsYXk6IGZsZXg7XG5cdGZsZXgtZGlyZWN0aW9uOiByb3c7XG5cdGZsZXgtd3JhcDogbm93cmFwO1xuXHRqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcblx0YWxpZ24taXRlbXM6IHRvcDtcblxuXHRtYXJnaW46IDAgYXV0bztcblx0d2lkdGg6IDEwMCU7XG5cdHZlcnRpY2FsLWFsaWduOiB0b3A7XG5cblx0I2xlZnQtYXR0LWhlYWRzIHtcblx0XHRvcmRlcjoxO1xuXHRcdGRpc3BsYXk6IGlubGluZS1ibG9jaztcblx0XHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuXHR9XG5cblx0I2xlZnQtdG9rZW5zIHtcblx0XHRvcmRlcjogMjtcblx0XHR0ZXh0LWFsaWduOiByaWdodDtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuXHR9XG5cblxuXHQjYXRuLWRpc3BsYXkge1xuXHRcdG9yZGVyOiAzO1xuXHRcdHZlcnRpY2FsLWFsaWduOiB0b3A7XG5cdH1cblxuXHQjcmlnaHQtdG9rZW5zIHtcblx0XHRvcmRlcjogNDtcblx0XHR0ZXh0LWFsaWduOiBsZWZ0O1xuXHRcdHZlcnRpY2FsLWFsaWduOiB0b3A7XG5cdH1cblxuXHQjcmlnaHQtYXR0LWhlYWRzIHtcblx0XHRvcmRlcjogNTtcblx0XHR2ZXJ0aWNhbC1hbGlnbjogdG9wO1xuXHR9XG5cdFxufVxuXG4uYXR0LXJlY3Qge1xuXHR0cmFuc2l0aW9uOiBmaWxsIDAuMXM7XG59XG5cbi50b2tlbiB7XG5cdGRpc3BsYXk6IGJsb2NrO1xufVxuXG4uYXRuLWN1cnZlIHtcblx0ZmlsbDogbm9uZTtcblx0Ly8gc3Ryb2tlLXdpZHRoOiAzO1xuXHRzdHJva2U6IHB1cnBsZTtcbn1cblxuLm1hc2tlZC10b2tlbiB7XG5cdGNvbG9yOiByZ2JhKDAsMCwwLDAuMilcbn1cblxuLnVuc2VsZWN0ZWQge1xuXHRmaWxsOiBncmF5O1xufVxuXG4uc2VsZWN0ZWQtdG9rZW4ge1xuXHRib3JkZXItc3R5bGU6IHNvbGlkO1xuXHRib3JkZXItd2lkdGg6IDNweDtcblx0Ym9yZGVyLWNvbG9yOiByZ2IoMTUzLCAxOTYsIDApO1xufVxuXG4vKiBUaGUgc3dpdGNoIC0gdGhlIGJveCBhcm91bmQgdGhlIHNsaWRlciAqL1xuLnN3aXRjaCB7XG5cdHBvc2l0aW9uOiByZWxhdGl2ZTtcblx0ZGlzcGxheTogaW5saW5lLWJsb2NrO1xuXHR3aWR0aDogNjBweDtcblx0aGVpZ2h0OiAzNHB4O1xuXG4vKiBIaWRlIGRlZmF1bHQgSFRNTCBjaGVja2JveCAqL1xuXHRpbnB1dCB7XG5cdFx0b3BhY2l0eTogMDtcblx0XHR3aWR0aDogMDtcblx0XHRoZWlnaHQ6IDA7XG5cdH1cbn1cblxuLyogVGhlIHNsaWRlciAqL1xuLnNob3J0LXNsaWRlciB7XG5cdHBvc2l0aW9uOiBhYnNvbHV0ZTtcblx0Y3Vyc29yOiBwb2ludGVyO1xuXHR0b3A6IDA7XG5cdGxlZnQ6IDA7XG5cdHJpZ2h0OiAwO1xuXHRib3R0b206IDA7XG5cdGJhY2tncm91bmQtY29sb3I6ICNjY2M7XG5cdC13ZWJraXQtdHJhbnNpdGlvbjogLjRzO1xuXHR0cmFuc2l0aW9uOiAuNHM7XG5cblx0JjpiZWZvcmUge1xuXHRcdHBvc2l0aW9uOiBhYnNvbHV0ZTtcblx0XHRjb250ZW50OiBcIlwiO1xuXHRcdGhlaWdodDogMjZweDtcblx0XHR3aWR0aDogMjZweDtcblx0XHRsZWZ0OiA0cHg7XG5cdFx0Ym90dG9tOiA0cHg7XG5cdFx0YmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG5cdFx0LXdlYmtpdC10cmFuc2l0aW9uOiAuNHM7XG5cdFx0dHJhbnNpdGlvbjogLjRzO1xuXHR9XG59XG5cbmlucHV0OmNoZWNrZWQgKyAuc2hvcnQtc2xpZGVyIHtcblx0YmFja2dyb3VuZC1jb2xvcjogIzIxOTZGMztcbn1cblxuaW5wdXQ6Zm9jdXMgKyAuc2hvcnQtc2xpZGVyIHtcblx0Ym94LXNoYWRvdzogMCAwIDFweCAjMjE5NkYzO1xufVxuXG5pbnB1dDpjaGVja2VkICsgLnNob3J0LXNsaWRlcjpiZWZvcmUge1xuXHQtd2Via2l0LXRyYW5zZm9ybTogdHJhbnNsYXRlWCgyNnB4KTtcblx0LW1zLXRyYW5zZm9ybTogdHJhbnNsYXRlWCgyNnB4KTtcblx0dHJhbnNmb3JtOiB0cmFuc2xhdGVYKDI2cHgpO1xufVxuXG4vKiBSb3VuZGVkIHNsaWRlcnMgKi9cbi5zaG9ydC1zbGlkZXIucm91bmQge1xuXHRib3JkZXItcmFkaXVzOiAzNHB4O1xufVxuXG4uc2hvcnQtc2xpZGVyLnJvdW5kOmJlZm9yZSB7XG5cdGJvcmRlci1yYWRpdXM6IDUwJTtcbn1cblxuI3NlbGVjdC1hbGwtaGVhZHN7IFxuXHRtYXJnaW4tdG9wOiAyMHB4O1xuXHRtYXJnaW4tYm90dG9tOiAyMHB4O1xufSIsIiNjb3JwdXMtdmlzIHtcbiAgbWFyZ2luOiAwIGF1dG87XG5cbiAgI21haW4tY29ycHVzLXZpcyB7XG4gICAgZGlzcGxheTogLXdlYmtpdC1mbGV4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG5cbiAgICAjY29ycHVzLW1hdC1jb250YWluZXIge1xuICAgICAgLXdlYmtpdC1mbGV4OiBpbml0aWFsO1xuICAgICAgZmxleDogaW5pdGlhbDtcbiAgICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7XG4gICAgICBmbG9hdDogbGVmdDtcblxuICAgICAgLmNvcnB1cy1tYXQge1xuICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICAgIG1hcmdpbi1yaWdodDogMC4wNWVtO1xuICAgICAgICBtYXJnaW4tbGVmdDogMC4wNWVtO1xuICAgICAgfVxuXG4gICAgICAub2Zmc2V0LTAge1xuICAgICAgICBib3JkZXI6IDAuMmVtIHNvbGlkIGJsYWNrO1xuICAgICAgfVxuXG4gICAgICAubWF0LWhvdmVyLWRpc3BsYXkge1xuICAgICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjAwLCAyMDAsIDIwMCwgMSk7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDhweCA4cHggMXB4IDhweDtcbiAgICAgICAgbWFyZ2luOiBhdXRvO1xuICAgICAgICBwIHtcbiAgICAgICAgICBtYXJnaW46IGF1dG87XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAjY29ycHVzLXNpbWlsYXItc2VudGVuY2VzLWRpdiB7XG4gICAgICAtd2Via2l0LWZsZXg6IDE7XG4gICAgICBmbGV4OiAxO1xuICAgICAgdmVydGljYWwtYWxpZ246IHRvcDtcbiAgICAgIGZsb2F0OiBsZWZ0O1xuICAgICAgbWF4LXdpZHRoOiA4MCU7XG4gICAgICBtYXgtaGVpZ2h0OiAxMDAlO1xuXG4gICAgICAuaG92ZXJlZC1jb2wge1xuICAgICAgICBjb2xvcjogb3JhbmdlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC5idG4ge1xuICAgIG1hcmdpbi1sZWZ0OiAwLjI1ZW07XG4gIH1cblxuICAuaW5zcGVjdG9yLXJvdyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbWFyZ2luLWxlZnQ6IDEwcHg7XG4gICAgcGFkZGluZy10b3A6IDAuNWVtO1xuICAgIHBhZGRpbmctYm90dG9tOiAwLjVlbTtcbiAgfVxuXG4gIC5pbnNwZWN0b3ItY2VsbCB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIG1hcmdpbi1yaWdodDogM3B4O1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gIH1cblxuICAvKiBUb29sdGlwIGNvbnRhaW5lciAqL1xuICAuY2VsbHRvb2x0aXAge1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IGRvdHRlZCBibGFjazsgLyogSWYgeW91IHdhbnQgZG90cyB1bmRlciB0aGUgaG92ZXJhYmxlIHRleHQgKi9cbiAgfVxuXG4gIC8qIFRvb2x0aXAgdGV4dCAqL1xuICAuY2VsbHRvb2x0aXAgLnRvb2x0aXB0ZXh0IHtcbiAgICB2aXNpYmlsaXR5OiBoaWRkZW47XG4gICAgd2lkdGg6IDEyMHB4O1xuICAgIGJhY2tncm91bmQtY29sb3I6IGJsYWNrO1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICBwYWRkaW5nOiA1cHggMDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG5cbiAgICAvKiBQb3NpdGlvbiB0aGUgdG9vbHRpcCB0ZXh0IC0gc2VlIGV4YW1wbGVzIGJlbG93ISAqL1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgfVxuXG4gIC8qIFNob3cgdGhlIHRvb2x0aXAgdGV4dCB3aGVuIHlvdSBtb3VzZSBvdmVyIHRoZSB0b29sdGlwIGNvbnRhaW5lciAqL1xuICAuY2VsbHRvb2x0aXA6aG92ZXIgLnRvb2x0aXB0ZXh0IHtcbiAgICB3aWR0aDogMTIwcHg7XG4gICAgYm90dG9tOiAxMDAlO1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLTYwcHg7IC8qIFVzZSBoYWxmIG9mIHRoZSB3aWR0aCAoMTIwLzIgPSA2MCksIHRvIGNlbnRlciB0aGUgdG9vbHRpcCAqL1xuICAgIHZpc2liaWxpdHk6IHZpc2libGU7XG4gIH1cblxuICAvKiBBZGQgbGl0dGxlIGFycm93IHRvIGJveCAqL1xuICAuY2VsbHRvb2x0aXAgLnRvb2x0aXB0ZXh0OjphZnRlciB7XG4gICAgY29udGVudDogXCIgXCI7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMTAwJTsgLyogQXQgdGhlIGJvdHRvbSBvZiB0aGUgdG9vbHRpcCAqL1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtYXJnaW4tbGVmdDogLTVweDtcbiAgICBib3JkZXItd2lkdGg6IDVweDtcbiAgICBib3JkZXItc3R5bGU6IHNvbGlkO1xuICAgIGJvcmRlci1jb2xvcjogYmxhY2sgdHJhbnNwYXJlbnQgdHJhbnNwYXJlbnQgdHJhbnNwYXJlbnQ7XG4gIH1cblxuICAubWF0Y2hlZC1jZWxsIHtcbiAgICBib3JkZXItc3R5bGU6IHNvbGlkO1xuICAgIGJvcmRlci1jb2xvcjogcmdiKDE1MywgMTk2LCAwKTtcbiAgICBib3JkZXItd2lkdGg6IDNweDtcbiAgICBib3JkZXItcmFkaXVzOiAwLjRlbTtcbiAgfVxuXG4gIC5ncmF5LWNlbGwge1xuICAgIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuMzUpO1xuICB9XG4gIC5uZXh0LWNlbGwge1xuICAgIGNvbG9yOiByZ2JhKDIyOCwgMSwgMSwgMC44KTtcbiAgICAtbW96LWJveC1zaGFkb3c6IDAgMCAzcHggI2NjYztcbiAgICAtd2Via2l0LWJveC1zaGFkb3c6IDAgMCAzcHggI2NjYztcbiAgICBib3gtc2hhZG93OiAwIDAgM3B4ICNjY2M7XG4gIH1cbn1cbiIsIlxuXG4jaGlzdG9ncmFtcyB7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbWF4LXdpZHRoOiAxMDAlO1xuXG4gICAgLmhpc3RvZ3JhbSB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICBvdmVyZmxvdy14OiBhdXRvO1xuICAgIH1cbiAgICBcbiAgICBkaXYge1xuICAgICAgbWFyZ2luLXRvcDogMTBweDtcbiAgICB9XG5cbiAgICAjbWF0Y2hlZC1oaXN0b2dyYW0geyBcbiAgICAgIC5iYXIge1xuXG4gICAgICAgfVxuICAgIH1cbiAgXG4gICAgI21heC1hdHQtaGlzdG9ncmFtIHsgXG4gICAgICAuYmFyIHtcbiAgICAgICAgICBmaWxsOiBibGFjaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAucG9zLXNlbGVjdG9yIHtcbiAgICBtYXJnaW4tYm90dG9tOiA0MHB4O1xuICB9IiwiQGltcG9ydCBcInBhbGV0dGUuc2Nzc1wiO1xuLy9AaW1wb3J0IFwiTGF0b0xpZ2h0LnNjc3NcIjtcbkBpbXBvcnQgXCIuLi9mb250cy9wbGV4X3NhbnMuY3NzXCI7XG5AaW1wb3J0IFwiYmFzZVwiO1xuQGltcG9ydCBcIlNlbnRlbmNlSW5wdXRcIjtcbkBpbXBvcnQgXCJBdHRlbnRpb25Db25uZWN0b3JDb250cm9sc1wiO1xuQGltcG9ydCBcIkNvcnB1c1Zpc1wiO1xuQGltcG9ydCBcIkhpc3RvZ3JhbXNcIjtcblxuYm9keSB7XG4gIGZvbnQtZmFtaWx5OiAnSUJNIFBsZXggU2Fucyc7XG59XG5cbi5sYXllckNoZWNrYm94IHtcbiAgYmFja2dyb3VuZC1jb2xvcjogbGlnaHRncmV5O1xuICBwYWRkaW5nLWxlZnQ6IDhweDtcbiAgcGFkZGluZy1yaWdodDogOHB4O1xuXG4gICYuYWN0aXZle1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIGJhY2tncm91bmQtY29sb3I6ICM2YzcwNjc7XG4gIH1cbn1cblxuLm1haW4tZ3JpZCB7XG4gIHdpZHRoOiAxMDAlO1xuICBkaXNwbGF5OiBncmlkO1xuICBncmlkLXRlbXBsYXRlLWNvbHVtbnM6IDAuMThmciAwLjJmciAwLjJmciAwLjA0ZnIgMC4yZnIgMC4yZnIgMC4xOGZyO1xuICBvdmVyZmxvdzogYXV0bztcbiAgbWF4LWhlaWdodDogMTAwdmg7XG59XG5cbi5sZWZ0LWhhbGYge1xuICBncmlkLWNvbHVtbi1zdGFydDogMTtcbiAgZ3JpZC1jb2x1bW4tZW5kOiA0O1xuICBtYXJnaW4tbGVmdDogMTBweDtcbiAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xufVxuXG4udnBhcnRpYWwtOTAge1xuICBtYXgtaGVpZ2h0OiA5MHZoO1xufVxuXG4udnBhcnRpYWwtOTUge1xuICBtYXgtaGVpZ2h0OiA5NXZoO1xufVxuXG4ucmlnaHQtaGFsZiB7XG4gIGdyaWQtY29sdW1uLXN0YXJ0OiA1O1xuICBncmlkLWNvbHVtbi1lbmQ6IDk7XG4gIG1heC1oZWlnaHQ6IDk4dmg7XG59XG5cbi52ZXJ0aWNhbC1zZXBhcmF0b3Ige1xuICBib3JkZXItbGVmdDogdGhpY2sgc29saWQgIzQyMjIyMjk4O1xuICBtYXJnaW46IDAgYXV0bztcbiAgbWFyZ2luLXRvcDogMTBweDtcbiAgbWFyZ2luLWJvdHRvbTogMTBweDtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBncmlkLWNvbHVtbi1zdGFydDogNDtcbiAgZ3JpZC1jb2x1bW4tZW5kOiA1O1xuICBncmlkLXJvdy1zdGFydDogMTtcbiAgZ3JpZC1yb3ctZW5kOiA1O1xufVxuXG4jdmlzLWJyZWFrIHtcbiAgaGVpZ2h0OiAxNXB4O1xufVxuXG5sYWJlbCB7XG4gIG1hcmdpbi1sZWZ0OiA1cHg7XG59XG5cbi8vIGhlYWRlciB7XG4vLyAgIGZvbnQtc2l6ZTogMmVtO1xuLy8gfVxuXG4jaGVhZGVyIHtcbiAgd2lkdGg6IDEwMCU7XG4gIGJhY2tncm91bmQtY29sb3I6IGxpZ2h0Z3JheTtcbiAgaGVpZ2h0OiA0MHB4O1xuICBtYXJnaW4tYm90dG9tOiA1cHg7XG5cbiAgLmhlYWRlci1sb2dve1xuICAgIGhlaWdodDogMjBweDtcbiAgICBkaXNwbGF5OmlubGluZS1ibG9jaztcbiAgICBtYXJnaW4tbGVmdDogMTBweDtcbiAgICBtYXJnaW4tdG9wOiA1cHg7XG4gICAgbWFyZ2luLWJvdHRvbTogNXB4O1xuICB9XG4gIC5oZWFkZXItaW5mb3tcbiAgICBmb250LXNpemU6IDlwdDtcbiAgICBoZWlnaHQ6IDMwcHg7XG4gICAgZGlzcGxheTppbmxpbmUtYmxvY2s7XG4gICAgZmxvYXQ6cmlnaHQ7XG4gICAgbWFyZ2luLXJpZ2h0OiAxMHB4O1xuICAgIG1hcmdpbi10b3A6IDEwcHg7XG4gICAgLy9tYXJnaW4tYm90dG9tOiA1cHg7XG4gIH1cblxuXG4gICNoZWFkZXJ0ZXh0e1xuICAgIHRleHQtYWxpZ246IGNlbnRlciA7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGZvbnQtc2l6ZTogMThweDtcbiAgICBtYXJnaW4tbGVmdDogMzAlO1xuICAgIG1hcmdpbi10b3A6IDVweDtcbiAgICBtYXJnaW4tYm90dG9tOiA1cHg7XG4gIH1cbn1cblxuLmhpZ2hsaWdodGVkIHtcbiAgYmFja2dyb3VuZDogcmdiYSgxNTIsIDgzLCAyMTYsIDAuOCk7XG59XG5cbiNtZXRhLWRyb3Bkb3duIHtcbiAgbWFyZ2luLWJvdHRvbTogMC43NWVtO1xuICBtYXJnaW4tbGVmdDogNGVtO1xufVxuXG4jcG9zaXRpb24tbWV0YS1kcm9wZG93biB7XG4gIG1hcmdpbi1ib3R0b206IDAuNzVlbTtcbiAgbWFyZ2luLWxlZnQ6IDRlbTtcbn1cblxuXG4jY29ycHVzLWNvbnRyb2wtYnV0dG9ucyB7XG4gIG1hcmdpbi1ib3R0b206IDFlbTtcbiAgcG9zaXRpb246IGZpeGVkIHJlbGF0aXZlO1xuICBzcGFuIHtcbiAgICBtYXJnaW4tbGVmdDo1cHg7XG4gIH1cbn1cblxuI3NlbGVjdGVkLWhlYWRzIHtcbiAgbWFyZ2luLWJvdHRvbTogMWVtO1xufVxuXG4jY29ycHVzLXNlbGVjdGlvbi1kZXNjcmlwdGlvbiB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXJpZ2h0OiAxNXB4O1xufVxuXG4jY29ycHVzLXF1ZXJ5aW5nIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAuYnRuIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIH1cbn1cblxuI3VzYWdlLWluZm8ge1xuICBtYXJnaW4tdG9wOiAxMHB4O1xuICBjb2xvcjogcmdiKDg3LCA4NywgODcpO1xuICBmb250LXNpemU6IDE0cHg7XG59XG5cbi50aWNrIHtcbiAgZm9udC1zaXplOiAxOHB4O1xufVxuXG4jY29ubmVjdG9yLWNvbnRhaW5lciB7XG4gIC5tYXQtaG92ZXItZGlzcGxheXtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICBkaXNwbGF5OiBibG9jaztcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdmlzaWJpbGl0eTogaGlkZGVuO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjAwLCAyMDAsIDIwMCwgMC45Myk7XG4gICAgZm9udC1zaXplOiAxNHB4O1xuICAgIHAge1xuICAgICAgbWFyZ2luOiA0cHggMXB4IDFweCA0cHg7XG4gICAgICAvLyBtYXJnaW46IGF1dG87XG4gICAgfVxuICB9XG59XG5cbi5yaWdodC10b2tlbi1ob3ZlciB7XG4gICAgYm9yZGVyLXJhZGl1czogMXB4IDhweCA4cHggOHB4O1xuICAgIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbi5sZWZ0LXRva2VuLWhvdmVyIHtcbiAgICBib3JkZXItcmFkaXVzOiA4cHggMXB4IDhweCA4cHg7XG4gICAgdGV4dC1hbGlnbjogcmlnaHQ7XG59XG5cbi5uZXh0LXRva2VuIHtcbiAgY29sb3I6IHJnYmEoMjI4LCAxLCAxLCAwLjgpO1xuICAtbW96LWJveC1zaGFkb3c6IDAgMCAzcHggI2NjYztcbiAgLXdlYmtpdC1ib3gtc2hhZG93OiAwIDAgM3B4ICNjY2M7XG4gIGJveC1zaGFkb3c6IDAgMCAzcHggI2NjYztcbn0iXSwic291cmNlUm9vdCI6IiJ9*/ \ No newline at end of file diff --git a/client/dist/main.js b/client/dist/main.js new file mode 100644 index 0000000000000000000000000000000000000000..32926ab7443c6287ef1eacfff813e661b0a9e687 --- /dev/null +++ b/client/dist/main.js @@ -0,0 +1,4192 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // install a JSONP callback for chunk loading +/******/ function webpackJsonpCallback(data) { +/******/ var chunkIds = data[0]; +/******/ var moreModules = data[1]; +/******/ var executeModules = data[2]; +/******/ +/******/ // add "moreModules" to the modules object, +/******/ // then flag all "chunkIds" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0, resolves = []; +/******/ for(;i < chunkIds.length; i++) { +/******/ chunkId = chunkIds[i]; +/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ resolves.push(installedChunks[chunkId][0]); +/******/ } +/******/ installedChunks[chunkId] = 0; +/******/ } +/******/ for(moduleId in moreModules) { +/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { +/******/ modules[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(parentJsonpFunction) parentJsonpFunction(data); +/******/ +/******/ while(resolves.length) { +/******/ resolves.shift()(); +/******/ } +/******/ +/******/ // add entry modules from loaded chunk to deferred list +/******/ deferredModules.push.apply(deferredModules, executeModules || []); +/******/ +/******/ // run deferred modules when all chunks ready +/******/ return checkDeferredModules(); +/******/ }; +/******/ function checkDeferredModules() { +/******/ var result; +/******/ for(var i = 0; i < deferredModules.length; i++) { +/******/ var deferredModule = deferredModules[i]; +/******/ var fulfilled = true; +/******/ for(var j = 1; j < deferredModule.length; j++) { +/******/ var depId = deferredModule[j]; +/******/ if(installedChunks[depId] !== 0) fulfilled = false; +/******/ } +/******/ if(fulfilled) { +/******/ deferredModules.splice(i--, 1); +/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); +/******/ } +/******/ } +/******/ +/******/ return result; +/******/ } +/******/ +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // Promise = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ "main": 0 +/******/ }; +/******/ +/******/ var deferredModules = []; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; +/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); +/******/ jsonpArray.push = webpackJsonpCallback; +/******/ jsonpArray = jsonpArray.slice(); +/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); +/******/ var parentJsonpFunction = oldJsonpFunction; +/******/ +/******/ +/******/ // add entry module to deferred list +/******/ deferredModules.push(["./ts/main.ts","vendor"]); +/******/ // run deferred modules when ready +/******/ return checkDeferredModules(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./css/main.scss": +/*!***********************!*\ + !*** ./css/main.scss ***! + \***********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +// extracted by mini-css-extract-plugin + +/***/ }), + +/***/ "./node_modules/file-loader/dist/cjs.js?name=exBERT.html!./exBERT.html": +/*!*****************************************************************************!*\ + !*** ./node_modules/file-loader/dist/cjs.js?name=exBERT.html!./exBERT.html ***! + \*****************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__.p + "exBERT.html"; + +/***/ }), + +/***/ "./node_modules/file-loader/dist/cjs.js?name=index.html!./index.html": +/*!***************************************************************************!*\ + !*** ./node_modules/file-loader/dist/cjs.js?name=index.html!./index.html ***! + \***************************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__.p + "index.html"; + +/***/ }), + +/***/ "./ts/api/demoAPI.ts": +/*!***************************!*\ + !*** ./ts/api/demoAPI.ts ***! + \***************************/ +/*! exports provided: DemoAPI */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DemoAPI", function() { return DemoAPI; }); +const DemoAPI = { + "527fdac4404bf9ba5412646ad457950d4482762c": "527fdac4404bf9ba5412646ad457950d4482762c.json", + "59b4acc05f1d80ecbef1c23eaf2fda10222cb257": "59b4acc05f1d80ecbef1c23eaf2fda10222cb257.json", + "354992f2ee236604c874a3a627e4042bc68586f8": "354992f2ee236604c874a3a627e4042bc68586f8.json", + "5015e5a318605cea6808538db14d8af16887b076": "5015e5a318605cea6808538db14d8af16887b076.json", + "3c9aa152ac894306040703c5095599b199cad1a9": "3c9aa152ac894306040703c5095599b199cad1a9.json", + "0fece0c87203e83afd1674b5aeebaed0f5fa0562": "0fece0c87203e83afd1674b5aeebaed0f5fa0562.json", + "d3a0e4045ea48a275ce51a6af0280406060f47cf": "d3a0e4045ea48a275ce51a6af0280406060f47cf.json", + "ed98d751ab9b6a4a0e85e9332b420a4c13ab75a7": "ed98d751ab9b6a4a0e85e9332b420a4c13ab75a7.json", + "0d24ae08eeb21af82c666cbe2ac0646ed9c9d9a6": "0d24ae08eeb21af82c666cbe2ac0646ed9c9d9a6.json", + "6de053b3b8a4d904780c9a6545a0a63cbbb2b144": "6de053b3b8a4d904780c9a6545a0a63cbbb2b144.json", + "f68df23365faf02f9c01439345bed66936ed85f7": "f68df23365faf02f9c01439345bed66936ed85f7.json", + "4608cb4fc00b43fff68098e85676fad57c940f02": "4608cb4fc00b43fff68098e85676fad57c940f02.json", + "dfcd50146da8d8122a5a57c2a3c0abce503ba94b": "dfcd50146da8d8122a5a57c2a3c0abce503ba94b.json", + "34c8629d4265d7f3ede3add42f3613b205d94c1c": "34c8629d4265d7f3ede3add42f3613b205d94c1c.json", + "db2dc252a786650f64395a0f5d181c0831019cbf": "db2dc252a786650f64395a0f5d181c0831019cbf.json", + "da4597d73d444757bde9176395bf31aad3334131": "da4597d73d444757bde9176395bf31aad3334131.json", + "a2ebf13d3c9371fcf738b9651824e2c3cd1ff8e0": "a2ebf13d3c9371fcf738b9651824e2c3cd1ff8e0.json", + "bc419238c20dd1c5cfe1cc427ab3d1e31353436a": "bc419238c20dd1c5cfe1cc427ab3d1e31353436a.json", + "84e8be9fe562fbd0487c03b55cc6b4f3fb8cd787": "84e8be9fe562fbd0487c03b55cc6b4f3fb8cd787.json", + "207e6c98a0e149dc7e6ed67118296d8a8c89b3c3": "207e6c98a0e149dc7e6ed67118296d8a8c89b3c3.json", + "c185a9349ba5a325acf8514e9b50de71280488aa": "c185a9349ba5a325acf8514e9b50de71280488aa.json", + "dde481a5cd3667ae8c6c5b5e1421dc882b6a2dd6": "dde481a5cd3667ae8c6c5b5e1421dc882b6a2dd6.json", + "f63e14e935d98948b4a0ebc9663400dbe4263348": "f63e14e935d98948b4a0ebc9663400dbe4263348.json", + "79b964d1a5c854deaeace26813f96994bb82aef2": "79b964d1a5c854deaeace26813f96994bb82aef2.json", + "3b1168ec96af00c4e887341e92a878f8752e1d17": "3b1168ec96af00c4e887341e92a878f8752e1d17.json", + "8c462bc298e3183efa8d9e863e25ea5d89806b03": "8c462bc298e3183efa8d9e863e25ea5d89806b03.json", + "9939698edaa25bbae9ee1d27864e698f13963f06": "9939698edaa25bbae9ee1d27864e698f13963f06.json", + "73f1ee497b3e7b6394e55726b18dbf9d514dcea6": "73f1ee497b3e7b6394e55726b18dbf9d514dcea6.json", + "c7cdb80bf813e1de241260aede6cd28ea65ccfae": "c7cdb80bf813e1de241260aede6cd28ea65ccfae.json", + "a96fed16eab1bf6d08e4001c02894d9c549df627": "a96fed16eab1bf6d08e4001c02894d9c549df627.json", + "a8eaf10da8dc75b42e72bdc7091776247fff9657": "a8eaf10da8dc75b42e72bdc7091776247fff9657.json", + "a8194f2309e1c71e977ef8d3be572ae00b0e91f2": "a8194f2309e1c71e977ef8d3be572ae00b0e91f2.json", + "2f4a15b66fcfb0c7a43a33d93763990282bfc5aa": "2f4a15b66fcfb0c7a43a33d93763990282bfc5aa.json", + "06095cef4a7f49b18f153e67e33fddb831a15b46": "06095cef4a7f49b18f153e67e33fddb831a15b46.json", + "4c93eaf0c0ce56f1e5d5100916abf4d31eb35da5": "4c93eaf0c0ce56f1e5d5100916abf4d31eb35da5.json", + "f8c40c67c851a0489f7480c99b31b4f606c0184b": "f8c40c67c851a0489f7480c99b31b4f606c0184b.json", + "e4e71f6ea57be2e05d62af0825a80f144421e02d": "e4e71f6ea57be2e05d62af0825a80f144421e02d.json", + "e7d9d520882782c7cfbffeadaaf22b4c0a081c7c": "e7d9d520882782c7cfbffeadaaf22b4c0a081c7c.json", + "4aa4eb10ead44a0a3c2dd95407017a928138b32b": "4aa4eb10ead44a0a3c2dd95407017a928138b32b.json", + "da31d55ee8cb01bcdb29572cb902b8e799685be2": "da31d55ee8cb01bcdb29572cb902b8e799685be2.json", + "e427181fb02bbf19f7bbb65c9d9389d2d9a41812": "e427181fb02bbf19f7bbb65c9d9389d2d9a41812.json", + "bbcab9e1ca60a851fd7ecfda80de470afa740936": "bbcab9e1ca60a851fd7ecfda80de470afa740936.json", + "4de96aa205076863c9fb4ea99e2ba86fa131ff76": "4de96aa205076863c9fb4ea99e2ba86fa131ff76.json", + "e4c6d1b3004e3cdd0c879a59639b5ce993207a99": "e4c6d1b3004e3cdd0c879a59639b5ce993207a99.json", + "fbc9da79b8bf39dc9998408526741f811a13e6aa": "fbc9da79b8bf39dc9998408526741f811a13e6aa.json", + "528554ee4e615c61287c40ed9a2aea69b91af6c9": "528554ee4e615c61287c40ed9a2aea69b91af6c9.json", + "5e7073c03c37d19826b2fb4a6599ccaedde492e4": "5e7073c03c37d19826b2fb4a6599ccaedde492e4.json", + "71c4a886cdee58a371ae2115311b150e84e555f6": "71c4a886cdee58a371ae2115311b150e84e555f6.json", + "4bce0970a465fe9b96305e06af19c5d9c97d7cc3": "4bce0970a465fe9b96305e06af19c5d9c97d7cc3.json", + "efdb1f0a70f22f80ff3cea0cb79bec717fc8b6f7": "efdb1f0a70f22f80ff3cea0cb79bec717fc8b6f7.json", + "174c6f786d139ce111381045d60d25682a168b99": "174c6f786d139ce111381045d60d25682a168b99.json", + "a8c23e88d6ca6d4efd2646b0742c0fa32dbd55a4": "a8c23e88d6ca6d4efd2646b0742c0fa32dbd55a4.json", + "f6949c28752de35a870efde308585acd46a25278": "f6949c28752de35a870efde308585acd46a25278.json", + "c1bdb8cbafd5d5d8f6bda2b4db16b6bc2d62e18a": "c1bdb8cbafd5d5d8f6bda2b4db16b6bc2d62e18a.json", + "2b81a8f602251cf40b4682c8cedb3966b912d7c6": "2b81a8f602251cf40b4682c8cedb3966b912d7c6.json", + "8f94e843d2510047fd1af46f249afe87ff49cc2f": "8f94e843d2510047fd1af46f249afe87ff49cc2f.json", + "4e3ddb51550c03c64fdbe5592526665100d32930": "4e3ddb51550c03c64fdbe5592526665100d32930.json", + "f816b23af9aa4312c80e668a66a156c934cb330c": "f816b23af9aa4312c80e668a66a156c934cb330c.json", + "2fe05a911a574b8a6d4b05eb13db9e09aaacad2d": "2fe05a911a574b8a6d4b05eb13db9e09aaacad2d.json", + "5c71496726395aaa4d0a65373fd1651b5a0e6b1f": "5c71496726395aaa4d0a65373fd1651b5a0e6b1f.json", +}; + + +/***/ }), + +/***/ "./ts/api/mainApi.ts": +/*!***************************!*\ + !*** ./ts/api/mainApi.ts ***! + \***************************/ +/*! exports provided: emptyTokenDisplay, API */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "emptyTokenDisplay", function() { return emptyTokenDisplay; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "API", function() { return API; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../data/TokenWrapper */ "./ts/data/TokenWrapper.ts"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _demoAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./demoAPI */ "./ts/api/demoAPI.ts"); +/* harmony import */ var object_hash__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! object-hash */ "./node_modules/object-hash/dist/object_hash.js"); +/* harmony import */ var object_hash__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(object_hash__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var _etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../etc/apiHelpers */ "./ts/etc/apiHelpers.ts"); +/* harmony import */ var _etc_URLHandler__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../etc/URLHandler */ "./ts/etc/URLHandler.ts"); + + + + + + + +const emptyTokenDisplay = new _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_1__["TokenDisplay"](); +const baseurl = _etc_URLHandler__WEBPACK_IMPORTED_MODULE_6__["URLHandler"].basicURL(); +/** + * A rewrite of `d3-fetch`'s `d3.json` callback. If an api call fails, make a backup call to specified url and payload, if specified. + * + * @param response Object expected at time of callback + * @param backupUrl Backup url in the event of fail + * @param backupPayload Backup payload if making a post request + */ +function responseJson(response, backupUrl = null, backupPayload = null) { + if (!response.ok) { + if (backupUrl != null) { + console.log("STATIC FILE NOT FOUND"); + return fetch(backupUrl, backupPayload).then(responseJson); + } + throw new Error(response.status + " " + response.statusText); + } + return response.json(); +} +/** + * Check first if the information being sent exists in a static demo file. If it does, send that. Otherwise, make a normal call to the server. + * + * @param toSend The packet of information to send to an API endpoint + * @param backupUrl Backup url in the event that the demo file is not found + * @param backupPayload Backup payload if demo file not found, for POST requests only + */ +function checkDemoAPI(toSend, backupUrl = null, backupPayload = null) { + const hsh = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + console.log("CHECKING DEMOAPI: " + hsh); + if (_demoAPI__WEBPACK_IMPORTED_MODULE_3__["DemoAPI"].hasOwnProperty(hsh)) { + // Relies on a symbolic link being present in the dist folder to the demo folder + const path = './demo/' + _demoAPI__WEBPACK_IMPORTED_MODULE_3__["DemoAPI"][hsh]; + console.log("TRYING TO SENDING STATIC: ", path); + const follow = (response) => responseJson(response, backupUrl, backupPayload); + return fetch(path).then(follow); + } + return d3__WEBPACK_IMPORTED_MODULE_0__["json"](backupUrl, backupPayload); +} +class API { + constructor(baseURL = null) { + this.baseURL = baseURL; + if (this.baseURL == null) { + this.baseURL = baseurl + '/api'; + } + } + getModelDetails(model, hashObj = null) { + const toSend = { + model: model + }; + const url = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["makeUrl"])(this.baseURL + "/get-model-details", toSend); + console.log("--- GET " + url); + if (hashObj != null) { + const key = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + d3__WEBPACK_IMPORTED_MODULE_0__["json"](url).then(r => { + hashObj[key] = r; + }); + } + return checkDemoAPI(toSend, url); + } + getMetaAttentions(model, sentence, layer, hashObj = null) { + const toSend = { + model: model, + sentence: sentence, + layer: layer + }; + const url = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["makeUrl"])(this.baseURL + "/attend+meta", toSend); + console.log("--- GET " + url); + // Add hash and value to hashObj + if (hashObj != null) { + const key = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + d3__WEBPACK_IMPORTED_MODULE_0__["json"](url).then(r => { + hashObj[key] = r; + }); + } + return checkDemoAPI(toSend, url); + } + /** + * Update the display based on the information that was already parsed from the passed sentence. + * + * @param a The displayed tokens in the columns + * @param sentenceA The original sentence that led to the tokenized information in `a` + * @param layer Which layer to search at + * @param hashObj If not null, store the information of the responses into the passed object. Used for creating demos. + */ + updateMaskedAttentions(model, tokens, sentence, layer, hashObj = null) { + const toSend = { + model: model, + tokens: ramda__WEBPACK_IMPORTED_MODULE_2__["map"](ramda__WEBPACK_IMPORTED_MODULE_2__["prop"]('text'), tokens.tokenData), + sentence: sentence, + // Empty masks need to be sent as a number, unfortunately. Choosing -1 for this + mask: tokens.maskInds.length ? tokens.maskInds : [-1], + layer: layer, + }; + const url = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["makeUrl"])(this.baseURL + '/update-mask'); + const payload = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["toPayload"])(toSend); + if (hashObj != null) { + // Add hash and value to hashObj for demo purposes + const key = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + d3__WEBPACK_IMPORTED_MODULE_0__["json"](url, payload).then(r => { + hashObj[key] = r; + }); + } + console.log("--- POST " + url, payload); + return checkDemoAPI(toSend, url, payload); + } + /** + * + * @param embedding Embedding of the word + * @param layer In the l'th layer + * @param k how many results to retrieve + */ + getNearestEmbeddings(model, corpus, embedding, layer, heads, k = 10, hashObj = null) { + const toSend = { + model: model, + corpus: corpus, + embedding: embedding, + layer: layer, + heads: heads, + k: k, + }; + const url = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["makeUrl"])(this.baseURL + '/k-nearest-embeddings', toSend); + console.log("--- GET " + url); + if (hashObj != null) { + const key = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + d3__WEBPACK_IMPORTED_MODULE_0__["json"](url).then(r => { + hashObj[key] = r; + }); + } + return checkDemoAPI(toSend, url); + } + getNearestContexts(model, corpus, context, layer, heads, k = 10, hashObj = null) { + const toSend = { + model: model, + corpus: corpus, + context: context, + layer: layer, + heads: heads, + k: k, + }; + const url = Object(_etc_apiHelpers__WEBPACK_IMPORTED_MODULE_5__["makeUrl"])(this.baseURL + '/k-nearest-contexts', toSend); + console.log("--- GET " + url); + if (hashObj != null) { + const key = object_hash__WEBPACK_IMPORTED_MODULE_4__["sha1"](toSend); + d3__WEBPACK_IMPORTED_MODULE_0__["json"](url).then(r => { + hashObj[key] = r; + }); + } + return checkDemoAPI(toSend, url); + } +} +; + + +/***/ }), + +/***/ "./ts/data/AttentionCapsule.ts": +/*!*************************************!*\ + !*** ./ts/data/AttentionCapsule.ts ***! + \*************************************/ +/*! exports provided: makeFromMetaResponse, AttentionWrapper */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeFromMetaResponse", function() { return makeFromMetaResponse; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttentionWrapper", function() { return AttentionWrapper; }); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _etc_Tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../etc/_Tools */ "./ts/etc/_Tools.ts"); +/* harmony import */ var _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @tensorflow/tfjs */ "./node_modules/@tensorflow/tfjs/dist/tf.esm.js"); + + + +/** + * Notes: + * + * - Also encapsulate the CLS/SEP info vs. no CLS/SEP info + * - When layer format changes from list, drop the index into conf.layer + */ +const bpeTokens = ["[CLS]", "[SEP]", "", "", "<|endoftext|>"]; +const findBadIndexes = (x) => _etc_Tools__WEBPACK_IMPORTED_MODULE_1__["findAllIndexes"](x.map(t => t.text), (a) => lodash__WEBPACK_IMPORTED_MODULE_0__["includes"](bpeTokens, a)); +function makeFromMetaResponse(r, isZeroed) { + const key = 'aa'; // Change this if backend response changes to be simpler + const currPair = r[key]; + const left = currPair.left; + const right = currPair.right; + const leftZero = _etc_Tools__WEBPACK_IMPORTED_MODULE_1__["findAllIndexes"](left.map(t => t.text), (a) => lodash__WEBPACK_IMPORTED_MODULE_0__["includes"](bpeTokens, a)); + const rightZero = _etc_Tools__WEBPACK_IMPORTED_MODULE_1__["findAllIndexes"](right.map(t => t.text), (a) => lodash__WEBPACK_IMPORTED_MODULE_0__["includes"](bpeTokens, a)); + return new AttentionWrapper(currPair.att, [leftZero, rightZero], isZeroed); +} +class AttentionWrapper { + constructor(att, badToks = [[], []], isZeroed = true) { + this.nLayers = 12; + this.nHeads = 12; + this.init(att, badToks, isZeroed); + } + init(att, badToks = [[], []], isZeroed) { + this.isZeroed = isZeroed; + this._att = att; + this._zeroedAttTensor = zeroRowCol(_tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_2__["tensor3d"](att), badToks[0], badToks[1]); + this._attTensor = _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_2__["tensor3d"](att); // If I put this first, buffer modifications change this too. + this.badToks = badToks; + } + updateFromNormal(r, isZeroed) { + const key = 'aa'; // Change this if backend response changes to be simpler + const currPair = r[key]; + const left = currPair.left; + const right = currPair.right; + const leftZero = findBadIndexes(left); + const rightZero = findBadIndexes(right); + this.init(currPair.att, [leftZero, rightZero], isZeroed); + } + get attTensor() { + const tens = this.isZeroed ? this._zeroedAttTensor : this._attTensor; + return tens; + } + get att() { + return this.attTensor.arraySync(); + } + zeroed(val) { + if (val == null) + return this.isZeroed; + this.isZeroed = val; + return this; + } + toggleZeroing() { + this.zeroed(!this.zeroed()); + } + _byHeads(heads) { + if (heads.length == 0) { + return _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_2__["zerosLike"](this._byHead(0)); + } + return this.attTensor.gather(heads, 0).sum(0); + } + _byHead(head) { + return this.attTensor.gather([head], 0).squeeze([0]); + } + byHeads(heads) { + return this._byHeads(heads).arraySync(); + } + byHead(head) { + return this._byHead(head).arraySync(); + } +} +function zeroRowCol(tens, rows, cols) { + let outTens = tens.clone(); + let atb = outTens.bufferSync(); + lodash__WEBPACK_IMPORTED_MODULE_0__["range"](atb.shape[0]).forEach((head) => { + lodash__WEBPACK_IMPORTED_MODULE_0__["range"](atb.shape[1]).forEach((i) => { + // Set rows to 0 + if (lodash__WEBPACK_IMPORTED_MODULE_0__["includes"](rows, i)) { + lodash__WEBPACK_IMPORTED_MODULE_0__["range"](atb.shape[2]).forEach((j) => { + atb.set(0, head, i, j); + }); + } + // Set cols to 0 + lodash__WEBPACK_IMPORTED_MODULE_0__["range"](atb.shape[2]).forEach((j) => { + if (lodash__WEBPACK_IMPORTED_MODULE_0__["includes"](cols, j)) + lodash__WEBPACK_IMPORTED_MODULE_0__["range"](atb.shape[1]).forEach((i) => { + atb.set(0, head, i, j); + }); + }); + }); + }); + return outTens; +} + + +/***/ }), + +/***/ "./ts/data/FaissSearchWrapper.ts": +/*!***************************************!*\ + !*** ./ts/data/FaissSearchWrapper.ts ***! + \***************************************/ +/*! exports provided: FaissSearchResultWrapper */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FaissSearchResultWrapper", function() { return FaissSearchResultWrapper; }); +/* harmony import */ var d3_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3-array */ "./node_modules/d3-array/src/index.js"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/SpacyInfo */ "./ts/etc/SpacyInfo.ts"); +/* harmony import */ var _etc_xramda__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../etc/xramda */ "./ts/etc/xramda.ts"); + + + + +// If value is not a string, don't try to make lowercase +const makeStringLower = ramda__WEBPACK_IMPORTED_MODULE_1__["ifElse"](ramda__WEBPACK_IMPORTED_MODULE_1__["is"](String), ramda__WEBPACK_IMPORTED_MODULE_1__["toLower"], ramda__WEBPACK_IMPORTED_MODULE_1__["identity"]); +function argMax(array) { + return [].map.call(array, (x, i) => [x, i]).reduce((r, a) => (a[0] > r[0] ? a : r))[1]; +} +class FaissSearchResultWrapper { + constructor(data, showNext = false) { + this.options = { + showNext: false + }; + this.data = data; + this.options.showNext = showNext; + } + get matchAtt() { + return this.showNext() ? "matched_att_plus_1" : "matched_att"; + } + get matchIdx() { + return this.showNext() ? "next_index" : "index"; + } + /** + * Add position info interpretable by the histogram + * + * @param countObj Represents the inforrmation to be displayed by the histogram + */ + countPosInfo() { + const attOffsets = this.data.map((d, i) => +d[this.matchAtt].out.offset_to_max); + const ctObj = { + offset: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(attOffsets) + }; + attOffsets.forEach(v => { + Object.keys(ctObj).forEach((k) => { + ctObj[k][v] += 1; + }); + }); + return ctObj; + } + countMaxAttKeys(indexOffset = 0) { + // The keys in the below object dictate what we count + const countObj = { + pos: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.pos), + dep: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.dep), + is_ent: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.is_ent), + }; + // Confusing: Show MATCHED WORD attentions, but NEXT WORD distribution + const getMaxToken = (d) => d.tokens[argMax(d.matched_att.out.att)]; + this.data.forEach((d, i) => { + const maxMatch = getMaxToken(d); + Object.keys(countObj).forEach(k => { + const val = makeStringLower(String(maxMatch[k])); + countObj[k][val] += 1; + }); + }); + const newCountObj = Object.assign(countObj, this.countPosInfo()); + return newCountObj; + } + countMatchedKeys(indexOffset = 0) { + // The keys in the below object dictate what we count + const countObj = { + pos: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.pos), + dep: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.dep), + is_ent: Object(_etc_xramda__WEBPACK_IMPORTED_MODULE_3__["initZero"])(_etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_2__["SpacyInfo"].TotalMetaOptions.is_ent), + }; + this.data.forEach(d => { + // Confusing: Show MATCHED WORD attentions, but NEXT WORD distribution + const match = d.tokens[d[this.matchIdx] + indexOffset]; + Object.keys(countObj).forEach(k => { + const val = makeStringLower(String(match[k])); + countObj[k][val] += 1; + }); + }); + return countObj; + } + getMatchedHistogram(indexOffset = 0) { + const totalHist = this.countMatchedKeys(indexOffset); + const filterZeros = (val, key) => val != 0; + const nonZero = ramda__WEBPACK_IMPORTED_MODULE_1__["map"](ramda__WEBPACK_IMPORTED_MODULE_1__["pickBy"](filterZeros), totalHist); + return nonZero; + } + getMaxAttHistogram() { + // const totalHist = this.countPosInfo() + const newHist = this.countMaxAttKeys(); + const filterZeros = (val, key) => val != 0; + const nonZero = ramda__WEBPACK_IMPORTED_MODULE_1__["map"](ramda__WEBPACK_IMPORTED_MODULE_1__["pickBy"](filterZeros), newHist); + return nonZero; + } + showNext(v) { + if (v == null) + return this.options.showNext; + this.options.showNext = v; + return this; + } +} + + +/***/ }), + +/***/ "./ts/data/TokenWrapper.ts": +/*!*********************************!*\ + !*** ./ts/data/TokenWrapper.ts ***! + \*********************************/ +/*! exports provided: TokenDisplay, TokenWrapper, sideToLetter */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TokenDisplay", function() { return TokenDisplay; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TokenWrapper", function() { return TokenWrapper; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sideToLetter", function() { return sideToLetter; }); +/* harmony import */ var _etc_Tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../etc/_Tools */ "./ts/etc/_Tools.ts"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); + + + +/** + * The original tokens, and the indexes that need to be masked + */ +const emptyFullResponse = [{ + text: '[SEP]', + embeddings: [], + contexts: [], + bpe_token: '', + bpe_pos: '', + bpe_dep: '', + bpe_is_ent: null, + topk_words: [], + topk_probs: [] + }]; +class TokenDisplay { + constructor(tokens = emptyFullResponse, maskInds = []) { + this.tokenData = tokens; + this.maskInds = maskInds; + } + /** + * Push idx to the mask idx list in order from smallest to largest + */ + mask(val) { + const currInd = lodash__WEBPACK_IMPORTED_MODULE_1__["indexOf"](this.maskInds, val); + if (currInd == -1) { + _etc_Tools__WEBPACK_IMPORTED_MODULE_0__["orderedInsert_"](this.maskInds, val); + } + else { + console.log(`${val} already in maskInds!`); + console.log(this.maskInds); + } + } + toggle(val) { + const currInd = lodash__WEBPACK_IMPORTED_MODULE_1__["indexOf"](this.maskInds, val); + if (currInd == -1) { + console.log(`Masking ${val}`); + this.mask(val); + } + else { + console.log(`Unmasking ${val}`); + this.unmask(val); + } + } + unmask(val) { + lodash__WEBPACK_IMPORTED_MODULE_1__["pull"](this.maskInds, val); + } + resetMask() { + this.maskInds = []; + } + length() { + return this.tokenData.length; + } + concat(other) { + const newTokens = lodash__WEBPACK_IMPORTED_MODULE_1__["concat"](this.tokenData, other.tokenData); + const newMask = lodash__WEBPACK_IMPORTED_MODULE_1__["concat"](this.maskInds, other.maskInds.map(x => x + this.length())); + return new TokenDisplay(newTokens, newMask); + } +} +class TokenWrapper { + constructor(r) { + this.updateFromResponse(r); + } + updateFromResponse(r) { + const tokensA = r.aa.left; + this.updateFromComponents(tokensA, []); + } + updateFromComponents(a, maskA) { + this.a = new TokenDisplay(a, maskA); + } + updateTokens(r) { + const desiredKeys = ['contexts', 'embeddings', 'topk_probs', 'topk_words']; + const newTokens = r.aa.left.map(v => ramda__WEBPACK_IMPORTED_MODULE_2__["pick"](desiredKeys, v)); + const pairs = ramda__WEBPACK_IMPORTED_MODULE_2__["zip"](this.a.tokenData, newTokens); + pairs.forEach((d, i) => { + Object.keys(d[1]).map(k => { + d[0][k] = d[1][k]; + }); + }); + } + /** + * Mask the appropriate sentence at the index indicated + */ + mask(sID, idx) { + this[sID].mask(idx); + const opts = ["a", "b"]; + const Na = this.a.length(); + } +} +function sideToLetter(side, atype) { + // const atype = conf.attType; + if (atype == "all") { + return "all"; + } + const out = side == "left" ? atype[0] : atype[1]; // No type checking? + return out; +} + + +/***/ }), + +/***/ "./ts/etc/SVGplus.ts": +/*!***************************!*\ + !*** ./ts/etc/SVGplus.ts ***! + \***************************/ +/*! exports provided: SVG, SVGMeasurements */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SVG", function() { return SVG; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SVGMeasurements", function() { return SVGMeasurements; }); +/* harmony import */ var d3_selection_multi__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3-selection-multi */ "./node_modules/d3-selection-multi/index.js"); + +/** + * Created by hen on 5/15/17. + * Modified by hoo on 4/16/19. + */ +class SVG { + static translate({ x, y }) { + return "translate(" + x + "," + y + ")"; + } + static rotate(deg) { + return `rotate(${deg})`; + } + static group(parent, classes, pos = { x: 0, y: 0 }) { + return parent.append('g').attrs({ + class: classes, + "transform": SVG.translate(pos) + }); + } +} +class SVGMeasurements { + constructor(baseElement, classes = '') { + this.measureElement = baseElement.append('text') + .attrs({ x: 0, y: -20, class: classes }); + } + textLength(text, style = null) { + this.measureElement.attr('style', style); + this.measureElement.text(text); + const tl = this.measureElement.node().getComputedTextLength(); + this.measureElement.text(''); + return tl; + } +} + + +/***/ }), + +/***/ "./ts/etc/SimpleEventHandler.ts": +/*!**************************************!*\ + !*** ./ts/etc/SimpleEventHandler.ts ***! + \**************************************/ +/*! exports provided: SimpleEventHandler */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleEventHandler", function() { return SimpleEventHandler; }); +/** + * Created by hen on 5/15/17. + * Modified by hoo on 4/16/19. + */ +class SimpleEventHandler { + constructor(element) { + this.element = element; + this.eventListeners = []; + } + bind(eventNames, eventFunction) { + for (const eventName of eventNames.split(' ')) { + this.eventListeners.push({ eventName, eventFunction }); + const eventFunctionWrap = e => eventFunction(e.detail, e); + this.element.addEventListener(eventName, eventFunctionWrap, false); + } + } + getListeners() { + return this.eventListeners; + } + trigger(eventName, detail) { + this.element.dispatchEvent(new CustomEvent(eventName, { detail })); + } +} + + +/***/ }), + +/***/ "./ts/etc/SpacyInfo.ts": +/*!*****************************!*\ + !*** ./ts/etc/SpacyInfo.ts ***! + \*****************************/ +/*! exports provided: SpacyInfo, spacyColors */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpacyInfo", function() { return SpacyInfo; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spacyColors", function() { return spacyColors; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _etc_colors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/colors */ "./ts/etc/colors.ts"); + + + +class SpacyInfo { + constructor() { + this.colorScale = this.createColorScales(); + } + createColorScales() { + const toScale = (keys) => { + const obj = ramda__WEBPACK_IMPORTED_MODULE_1__["zipObj"](ramda__WEBPACK_IMPORTED_MODULE_1__["map"](String, keys), _etc_colors__WEBPACK_IMPORTED_MODULE_2__["COLORS200"].slice(0, keys.length)); + return k => ramda__WEBPACK_IMPORTED_MODULE_1__["propOr"]("black", k, obj); + }; + const myColors = { + pos: toScale(SpacyInfo.TotalMetaOptions.pos), + dep: toScale(SpacyInfo.TotalMetaOptions.dep), + is_ent: toScale(SpacyInfo.TotalMetaOptions.is_ent), + ents: toScale(SpacyInfo.TotalMetaOptions.ents), + offset: d3__WEBPACK_IMPORTED_MODULE_0__["scaleOrdinal"]().range(['black']) + }; + return myColors; + } +} +SpacyInfo.EnglishMetaOptions = { + pos: ['punct', 'sym', 'x', 'adj', 'verb', 'conj', 'num', 'et', 'adv', 'x', 'adp', 'noun', 'propn', 'part', 'pron', 'space', 'intj'], + dep: ['root', 'ROOT', 'acl', 'acomp', 'advcl', 'advmod', 'agent', 'amod', 'appos', 'attr', 'aux', 'auxpass', 'case', 'cc', 'ccomp', 'compound', 'conj', 'cop', 'csubj', + 'csubjpass', 'dative', 'dep', 'det', 'dobj', 'expl', 'intj', 'mark', 'meta', 'neg', 'nn', 'nounmod', 'npmod', 'nsubj', 'nsubjpass', 'nummod', 'oprd', + 'obj', 'obl', 'parataxis', 'pcomp', 'pobj', 'poss', 'preconj', 'predet', 'prep', 'prt', 'punct', 'quantmod', 'relcl', 'root', 'xcomp', 'npadvmod'], + is_ent: [true, false], + ents: ['person', 'norp', 'fac', 'org', 'gpe', 'loc', 'product', 'event', 'work_of_art', 'law', 'language', 'date', 'time', 'percent', 'money', 'quantity', 'ordinal', + 'cardinal'], +}; +/** + * Obsolete. Represents the information that is included when trained on the universal corpus + */ +SpacyInfo.UniversalMetaOptions = { + pos: ['adj', 'adp', 'adv', 'aux', 'conj', 'cconj', 'det', 'intj', 'noun', 'num', 'part', 'pron', 'propn', 'punct', 'sconj', 'sym', 'verb', 'x', 'space'], + dep: ['acl', 'advcl', 'advmod', 'amod', 'appos', 'aux', 'case', 'cc', 'ccomp', 'clf', 'compound', 'conj', 'cop', 'csubj', 'dep', 'det', 'discourse', + 'dislocated', 'expl', 'fixed', 'flat', 'goeswith', 'iobj', 'list', 'mark', 'nmod', 'nsubj', 'nummod', 'obj', 'obl', 'orphan', 'parataxis', 'punct', 'reparandum', + 'root', 'vocative', 'xcomp'], + is_ent: [true, false], + ents: ['person', 'norp', 'fac', 'org', 'gpe', 'loc', 'product', 'event', 'work_of_art', 'law', 'language', 'date', 'time', 'percent', 'money', 'quantity', 'ordinal', + 'cardinal'], +}; +SpacyInfo.TotalMetaOptions = { + pos: ramda__WEBPACK_IMPORTED_MODULE_1__["union"](SpacyInfo.EnglishMetaOptions.pos, SpacyInfo.UniversalMetaOptions.pos), + dep: SpacyInfo.EnglishMetaOptions.dep, + is_ent: SpacyInfo.EnglishMetaOptions.is_ent, + ents: SpacyInfo.EnglishMetaOptions.ents, +}; +const spacyColors = new SpacyInfo(); + + +/***/ }), + +/***/ "./ts/etc/URLHandler.ts": +/*!******************************!*\ + !*** ./ts/etc/URLHandler.ts ***! + \******************************/ +/*! exports provided: URLHandler */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "URLHandler", function() { return URLHandler; }); +/** + * Created by hen on 5/15/17. + */ +class URLHandler { + static basicURL() { + const url_path = window.location.pathname.split('/').slice(0, -2).join('/'); + return window.location.origin + (url_path.length ? url_path : ''); + } + /** + * Read all URL parameters into a map. + * @returns {Map} the url parameters as a key-value store (ES6 map) + */ + static get parameters() { + // Adapted from: http://stackoverflow.com/questions/2090551/parse-query-string-in-javascript + const query = window.location.search.substring(1); + const vars = query.split('&'); + console.log(vars, "--- vars"); + const urlParameters = {}; + const isInt = x => (/^[0-9]+$/).test(x); + const isFloat = x => (/^[0-9]+\.[0-9]*$/).test(x); + const typeCast = val => { + if (isInt(val)) { + return Number.parseInt(val, 10); + } + else if (isFloat(val)) { + return Number.parseFloat(val); + } + // else: + return val; + }; + vars.forEach(v => { + if (v.length > 0) { + const splits = v.split('='); + const key = decodeURIComponent(splits[0]); + let raw_value = decodeURIComponent(splits[1]); + const isArray = raw_value.startsWith('..'); + if (isArray) { + raw_value = raw_value.slice(2); + } + if (raw_value.length < 1) { + urlParameters[key] = isArray ? [] : ''; + } + else if (isArray) { + urlParameters[key] = raw_value.split(',') + .map(val => typeCast(val)); + } + else { + urlParameters[key] = typeCast(raw_value); + } + } + }); + return urlParameters; + } + /** + * Generates an URL string from a map of url parameters + * @param {{}} urlParameters - the map of parameters + * @returns {string} - an URI string + */ + static urlString(urlParameters) { + const attr = []; + Object.keys(urlParameters).forEach(k => { + const v = urlParameters[k]; + if (v !== undefined) { + let value = v; + if (Array.isArray(v)) + value = '..' + v.join(','); + attr.push(encodeURI(k + '=' + value)); + } + }); + const url = window.location.pathname; + let res = url.substring(url.lastIndexOf('/') + 1); + if (attr.length > 0) { + res += '?' + attr.join('&'); + } + return res; + } + static updateURLParam(key, value, addToBrowserHistory = true) { + const currentParams = URLHandler.parameters; + currentParams[key] = value; + URLHandler.updateUrl(currentParams, addToBrowserHistory); + } + // /** + // * Generates a key-value map of all URL params and replaces replaceKeys + // * @param updateKeys + // */ + // static updateURLParams(updateKeys) { + // const currentParams = URLHandler.parameters; + // Object.keys(updateKeys).forEach((k) => currentParams[k] = updateKeys[k]) + // return currentParams; + // } + static updateUrl(urlParameters, addToBrowserHistory = true) { + if (addToBrowserHistory) { + window.history.pushState(urlParameters, '', URLHandler.urlString(urlParameters)); + } + else { + window.history.replaceState(urlParameters, '', URLHandler.urlString(urlParameters)); + } + } +} + + +/***/ }), + +/***/ "./ts/etc/Util.ts": +/*!************************!*\ + !*** ./ts/etc/Util.ts ***! + \************************/ +/*! exports provided: Util, Sel */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Util", function() { return Util; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sel", function() { return Sel; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); + +/** + * Created by hen on 5/15/17. + * Modifyed by hoo on 4/16/19. + */ +let the_unique_id_counter = 0; +class Util { + static simpleUId({ prefix = '' }) { + the_unique_id_counter += 1; + return prefix + the_unique_id_counter; + } +} +/** + * Selection utility functions should be static methods in the below class + */ +class Sel { +} +Sel.setSelVisible = (x) => x.attr("visibility", "visible"); +Sel.setSelHidden = (x) => x.attr("visibility", "hidden"); +Sel.setVisible = (x) => Sel.setSelVisible(d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](x)); +Sel.setHidden = (x) => Sel.setSelHidden(d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](x)); +Sel.hideElement = (hE) => hE.transition().styles({ + 'opacity': 0, + 'pointer-events': 'none', + 'display': 'none' +}); +Sel.unhideElement = (hE) => hE.transition().styles({ + 'opacity': 1, + 'pointer-events': null, + 'display': null +}); + + +/***/ }), + +/***/ "./ts/etc/_Tools.ts": +/*!**************************!*\ + !*** ./ts/etc/_Tools.ts ***! + \**************************/ +/*! exports provided: findAllIndexes, insertAt_, orderedInsert_, set2SortedArray, makeRandom */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findAllIndexes", function() { return findAllIndexes; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "insertAt_", function() { return insertAt_; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "orderedInsert_", function() { return orderedInsert_; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "set2SortedArray", function() { return set2SortedArray; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeRandom", function() { return makeRandom; }); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_0__); + +function ascOrder(n1, n2) { + if (n1 < n2) { + return -1; + } + else if (n1 > n2) { + return 1; + } + return 0; +} + +/** + * Find all indexes that match a particular predicate + */ +function findAllIndexes(array, predicate) { + let fromIndex = 0; + let results = []; + let i = lodash__WEBPACK_IMPORTED_MODULE_0__["findIndex"](array, predicate, fromIndex); + while (i != -1) { + results.push(i); + i = lodash__WEBPACK_IMPORTED_MODULE_0__["findIndex"](array, predicate, i + 1); + } + return results; +} +; +function insertAt_(array, val, ind) { + array.splice(ind, 0, val); + return array; +} +/** + * Convert a set to an ordered array + */ +function set2SortedArray(input) { + return Array.from(input).sort(ascOrder); +} +/** + * Insert a value into array in sorted order IN PLACE + * + * WARNING: Only handles numbers, sorted from least to greatest + * - Assumes already sorted array + */ +function orderedInsert_(array, val, coldstart = false) { + // Resort array if desired + if (coldstart) { + array.sort(ascOrder); + } + const ind = lodash__WEBPACK_IMPORTED_MODULE_0__["sortedIndex"](array, val); + return insertAt_(array, val, ind); +} +function makeRandom(len) { + const a = new Array(len).fill(0); + return a.map((x) => { return lodash__WEBPACK_IMPORTED_MODULE_0__["random"](-5, 5, true); }); +} + + +/***/ }), + +/***/ "./ts/etc/apiHelpers.ts": +/*!******************************!*\ + !*** ./ts/etc/apiHelpers.ts ***! + \******************************/ +/*! exports provided: makeUrl, toPayload */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "makeUrl", function() { return makeUrl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toPayload", function() { return toPayload; }); +/** + * Convert a JS object into GET URL parameters + * + * @param base Base URL atop which to add GET parameters + * @param params Object to insert into a URL string + */ +function makeUrl(base, params) { + if (params) { + let out = base + "?"; + Object.keys(params).forEach(k => { + out += k; + out += '='; + out += params[k]; + out += "&"; + }); + return out.replace(/&$/g, ""); + } + else { + return base; + } +} +; +/** + * Convert information in GET request into the message for a POST request + */ +const toPayload = (toSend) => { + return { + method: "POST", + body: JSON.stringify(toSend), + headers: { + "Content-type": "application/json; charset=UTF-8" + } + }; +}; + + +/***/ }), + +/***/ "./ts/etc/arrayUtils.ts": +/*!******************************!*\ + !*** ./ts/etc/arrayUtils.ts ***! + \******************************/ +/*! exports provided: sortWithIndices */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sortWithIndices", function() { return sortWithIndices; }); +/** + * Copies and sorts an array while keeping track of the indices. Currently only supports sorting max -> min. + * + * @param arr - Array to be copied and sorted + */ +function sortWithIndices(arr, fn) { + // If fn is not provided, default to sorting by max value + if (!fn) { + fn = function (left, right) { + return left[0] > right[0] ? -1 : 1; + }; + } + let out = { + arr: [], + sortIndices: [] + }; + let idxTracker = []; + for (let i = 0; i < arr.length; i++) { + idxTracker[i] = [arr[i], i]; + } + idxTracker.sort(function (left, right) { + return left[0] > right[0] ? -1 : 1; + }); + for (var j = 0; j < arr.length; j++) { + out.sortIndices.push(idxTracker[j][1]); + out.arr[j] = idxTracker[j][0]; + } + return out; +} + + +/***/ }), + +/***/ "./ts/etc/colors.ts": +/*!**************************!*\ + !*** ./ts/etc/colors.ts ***! + \**************************/ +/*! exports provided: COLORS200 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "COLORS200", function() { return COLORS200; }); +// Colors were generated to be as visually distinct as possible by: http://jnnnnn.github.io/category-colors-constrained.html +const COLORS200 = [ + "#3957ff", "#d3fe14", "#c9080a", "#fec7f8", "#0b7b3e", "#0bf0e9", "#c203c8", "#fd9b39", + "#888593", "#906407", "#98ba7f", "#fe6794", "#10b0ff", "#ac7bff", "#fee7c0", "#964c63", + "#1da49c", "#0ad811", "#bbd9fd", "#fe6cfe", "#297192", "#d1a09c", "#78579e", "#81ffad", + "#739400", "#ca6949", "#d9bf01", "#646a58", "#d5097e", "#bb73a9", "#ccf6e9", "#9cb4b6", + "#b6a7d4", "#9e8c62", "#6e83c8", "#01af64", "#a71afd", "#cfe589", "#d4ccd1", "#fd4109", + "#bf8f0e", "#2f786e", "#4ed1a5", "#d8bb7d", "#a54509", "#6a9276", "#a4777a", "#fc12c9", + "#606f15", "#3cc4d9", "#f31c4e", "#73616f", "#f097c6", "#fc8772", "#92a6fe", "#875b44", + "#699ab3", "#94bc19", "#7d5bf0", "#d24dfe", "#c85b74", "#68ff57", "#b62347", "#994b91", + "#646b8c", "#977ab4", "#d694fd", "#c4d5b5", "#fdc4bd", "#1cae05", "#7bd972", "#e9700a", + "#d08f5d", "#8bb9e1", "#fde945", "#a29d98", "#1682fb", "#9ad9e0", "#d6cafe", "#8d8328", + "#b091a7", "#647579", "#1f8d11", "#e7eafd", "#b9660b", "#a4a644", "#fec24c", "#b1168c", + "#188cc1", "#7ab297", "#4468ae", "#c949a6", "#d48295", "#eb6dc2", "#d5b0cb", "#ff9ffb", + "#fdb082", "#af4d44", "#a759c4", "#a9e03a", "#0d906b", "#9ee3bd", "#5b8846", "#0d8995", + "#f25c58", "#70ae4f", "#847f74", "#9094bb", "#ffe2f1", "#a67149", "#936c8e", "#d04907", + "#c3b8a6", "#cef8c4", "#7a9293", "#fda2ab", "#2ef6c5", "#807242", "#cb94cc", "#b6bdd0", + "#b5c75d", "#fde189", "#b7ff80", "#fa2d8e", "#839a5f", "#28c2b5", "#e5e9e1", "#bc79d8", + "#7ed8fe", "#9f20c3", "#4f7a5b", "#f511fd", "#09c959", "#bcd0ce", "#8685fd", "#98fcff", + "#afbff9", "#6d69b4", "#5f99fd", "#aaa87e", "#b59dfb", "#5d809d", "#d9a742", "#ac5c86", + "#9468d5", "#a4a2b2", "#b1376e", "#d43f3d", "#05a9d1", "#c38375", "#24b58e", "#6eabaf", + "#66bf7f", "#92cbbb", "#ddb1ee", "#1be895", "#c7ecf9", "#a6baa6", "#8045cd", "#5f70f1", + "#a9d796", "#ce62cb", "#0e954d", "#a97d2f", "#fcb8d3", "#9bfee3", "#4e8d84", "#fc6d3f", + "#7b9fd4", "#8c6165", "#72805e", "#d53762", "#f00a1b", "#de5c97", "#8ea28b", "#fccd95", + "#ba9c57", "#b79a82", "#7c5a82", "#7d7ca4", "#958ad6", "#cd8126", "#bdb0b7", "#10e0f8", + "#dccc69", "#d6de0f", "#616d3d", "#985a25", "#30c7fd", "#0aeb65", "#e3cdb4", "#bd1bee", + "#ad665d", "#d77070", "#8ea5b8", "#5b5ad0", "#76655e", "#598100", "#86757e", "#5ea068", +]; + + +/***/ }), + +/***/ "./ts/etc/types.ts": +/*!*************************!*\ + !*** ./ts/etc/types.ts ***! + \*************************/ +/*! exports provided: Toggled, NormBy, ModelKind */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Toggled", function() { return Toggled; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NormBy", function() { return NormBy; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModelKind", function() { return ModelKind; }); +var Toggled; +(function (Toggled) { + Toggled[Toggled["ADDED"] = 0] = "ADDED"; + Toggled[Toggled["REMOVED"] = 1] = "REMOVED"; +})(Toggled || (Toggled = {})); +var NormBy; +(function (NormBy) { + NormBy[NormBy["Row"] = 0] = "Row"; + NormBy[NormBy["Col"] = 1] = "Col"; + NormBy[NormBy["All"] = 2] = "All"; +})(NormBy || (NormBy = {})); +var ModelKind; +(function (ModelKind) { + ModelKind["Bidirectional"] = "bidirectional"; + ModelKind["Autoregressive"] = "autoregressive"; +})(ModelKind || (ModelKind = {})); + + +/***/ }), + +/***/ "./ts/etc/xd3.ts": +/*!***********************!*\ + !*** ./ts/etc/xd3.ts ***! + \***********************/ +/*! no exports provided */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); + +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.clear = function () { + this.selectAll('*').remove(); + return this; +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.toggleClass = function (className) { + this.classed(className, !this.classed(className)); + return this; +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.show = function () { + this.style('display', 'initial'); + return this; +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.hide = function () { + this.style('display', 'none'); + return this; +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.toggle = function () { + var isHidden = this.style('display') == 'none'; + return this.style('display', isHidden ? 'inherit' : 'none'); +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.after = function (tagName) { + var elements = []; + this.each(function () { + var element = document.createElement(tagName); + this.parentNode.insertBefore(element, this.nextSibling); + elements.push(element); + }); + return d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](elements); +}; +d3__WEBPACK_IMPORTED_MODULE_0__["selection"].prototype.before = function (tagName) { + var elements = []; + this.each(function () { + var element = document.createElement(tagName); + this.parentNode.insertBefore(element, this); + elements.push(element); + }); + return d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](elements); +}; + + +/***/ }), + +/***/ "./ts/etc/xramda.ts": +/*!**************************!*\ + !*** ./ts/etc/xramda.ts ***! + \**************************/ +/*! exports provided: objFromKeys, assignZero, initZero */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "objFromKeys", function() { return objFromKeys; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "assignZero", function() { return assignZero; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "initZero", function() { return initZero; }); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); + +/** + * Map a list as values to an object whose keys are the original list + */ +// (String -> b) -> [String] -> {String: b} +const objFromKeys = ramda__WEBPACK_IMPORTED_MODULE_0__["curry"]((fn, keys) => ramda__WEBPACK_IMPORTED_MODULE_0__["zipObj"](keys, ramda__WEBPACK_IMPORTED_MODULE_0__["map"](fn, keys))); +const assignZero = x => 0; +/** + * Given an list, create an object whose values are all 0 + */ +const initZero = objFromKeys(assignZero); + + +/***/ }), + +/***/ "./ts/main.ts": +/*!********************!*\ + !*** ./ts/main.ts ***! + \********************/ +/*! no exports provided */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _vis_myMain__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vis/myMain */ "./ts/vis/myMain.ts"); +/* harmony import */ var _api_mainApi__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./api/mainApi */ "./ts/api/mainApi.ts"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./data/TokenWrapper */ "./ts/data/TokenWrapper.ts"); +/* harmony import */ var _file_loader_name_exBERT_html_exBERT_html__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! file-loader?name=exBERT.html!../exBERT.html */ "./node_modules/file-loader/dist/cjs.js?name=exBERT.html!./exBERT.html"); +/* harmony import */ var _file_loader_name_exBERT_html_exBERT_html__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_exBERT_html_exBERT_html__WEBPACK_IMPORTED_MODULE_4__); +/* harmony import */ var _file_loader_name_index_html_index_html__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! file-loader?name=index.html!../index.html */ "./node_modules/file-loader/dist/cjs.js?name=index.html!./index.html"); +/* harmony import */ var _file_loader_name_index_html_index_html__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_file_loader_name_index_html_index_html__WEBPACK_IMPORTED_MODULE_5__); +/* harmony import */ var _css_main_scss__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../css/main.scss */ "./css/main.scss"); +/* harmony import */ var _css_main_scss__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_css_main_scss__WEBPACK_IMPORTED_MODULE_6__); + + + + +// import { Tester } from "../ts/test" + + + +function doMySvg() { + return new _vis_myMain__WEBPACK_IMPORTED_MODULE_0__["MainGraphic"](); +} +; +/** + * Create the static files needed for the demo. Save the keys and file paths to a json object that is then written to a file + * + * This will print the object after every call. When the key length is the expected length, right click in chrome and select "save as global variable" + * + * Then, in the console, type "copy(temp1)". Use sublime text (it is the best for handling large files) to paste this into the code and save it as ____.json + * + * @param sentence - The sentence to analyze + * @param maskInd - Which index to mask in the sentence. Atm, can only record one masking + * @param outDictPath - Where to save the object of hashkey: filepath + */ +function createDemos(sentence, maskInd, modelName, corpusName, outDictPath) { + const api = new _api_mainApi__WEBPACK_IMPORTED_MODULE_1__["API"](); + const layers = lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12); + const L = 0; + const contentHash = {}; // Map hash -> contents + // Get the base return for all page initializations + lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12).forEach(L => { + api.getMetaAttentions(modelName, sentence, L, contentHash).then(r0 => { + const tokCapsule = new _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_3__["TokenWrapper"](r0.payload); + // Unmasked response: + api.updateMaskedAttentions(modelName, tokCapsule.a, sentence, L, contentHash).then(r1 => { + // Masked word and searching responses: + tokCapsule.a.mask(maskInd); + api.updateMaskedAttentions(modelName, tokCapsule.a, sentence, L, contentHash).then(r2 => { + // Get search results by embedding + const embedding = r2['aa']['left'][maskInd].embeddings; + api.getNearestEmbeddings(modelName, corpusName, embedding, L, lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12), 50, contentHash).then(x => { + }); + // Get search results by context + const context = r2['aa']['left'][maskInd].contexts; + api.getNearestContexts(modelName, corpusName, context, L, lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12), 50, contentHash).then(x => { + console.log(Object.keys(contentHash).length); + console.log(contentHash); + }); + }); + }); + }); + }); +} +/** + * + * Observe how the demo creation process works. + * + * If desired to mask multiple words in the input for demo purposes, try looping over the mask inds and masking each one individually + * + * @param sentence The demo sentence + * @param maskInd Desired index to mask (can currently only accept a single mask index) + * @param outDictPath + */ +function inspectDemos(sentence, maskInd, modelName, corpusName, outDictPath) { + const api = new _api_mainApi__WEBPACK_IMPORTED_MODULE_1__["API"](); + const contentHash = {}; + // Get the base return for all page initializations + lodash__WEBPACK_IMPORTED_MODULE_2__["range"](1).forEach(L => { + api.getMetaAttentions(modelName, sentence, L, "").then(r0 => { + const tokCapsule = new _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_3__["TokenWrapper"](r0.payload); + // Unmasked response: + api.updateMaskedAttentions(modelName, tokCapsule.a, sentence, L, _api_mainApi__WEBPACK_IMPORTED_MODULE_1__["emptyTokenDisplay"]).then(r1 => { + // Masked word and searching responses: + tokCapsule.a.mask(maskInd); + api.updateMaskedAttentions(modelName, tokCapsule.a, sentence, L, _api_mainApi__WEBPACK_IMPORTED_MODULE_1__["emptyTokenDisplay"]).then(r2 => { + console.log(r2); + // Get search results by embedding + const embedding = r2['aa']['left'][maskInd].embeddings; + api.getNearestEmbeddings(modelName, corpusName, embedding, L, lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12), 50, contentHash).then(x => { + }); + // Get search results by context + const context = r2['aa']['left'][maskInd].contexts; + api.getNearestContexts(modelName, corpusName, context, L, lodash__WEBPACK_IMPORTED_MODULE_2__["range"](12), 50).then(x => { + }); + }); + }); + }); + }); +} +function replTest() { + // Tester.testAttWrapperConstructor() + // Tester.testUpdateMaskedAttention() + // Tester.testNjAray(); + // Tester.testRandomArrayCreation(); + // Tester.testFaissWrapper(); + // Tester.testD3Ordinal(); + // Tester.testFaissSearchResultsHist(); + // Tester.testReadingJSON(); +} +window.onload = () => { + doMySvg(); + // replTest(); + // createDemos("Chicken tastes absolutely delicious if you know what you're doing", 4, "") + console.log("Done loading window"); +}; + + +/***/ }), + +/***/ "./ts/uiConfig.ts": +/*!************************!*\ + !*** ./ts/uiConfig.ts ***! + \************************/ +/*! exports provided: UIConfig */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "UIConfig", function() { return UIConfig; }); +/* harmony import */ var _etc_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./etc/types */ "./ts/etc/types.ts"); +/* harmony import */ var _etc_Tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./etc/_Tools */ "./ts/etc/_Tools.ts"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _etc_URLHandler__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./etc/URLHandler */ "./ts/etc/URLHandler.ts"); + + + + + +const falsey = val => (new Set(['false', 0, "no", false, null, ""])).has(val); +const truthy = val => !falsey(val); +const toNumber = x => +x; +class UIConfig { + constructor() { + this._conf = {}; + this._nHeads = 12; // How do I automate this? + this._nLayers = null; + this.attType = 'aa'; // Don't allow this to be modified by the user. + this.fromURL(); + this.toURL(false); + } + fromURL() { + const params = _etc_URLHandler__WEBPACK_IMPORTED_MODULE_4__["URLHandler"].parameters; + this._conf = { + model: params['model'] || 'bert-base-cased', + modelKind: params['modelKind'] || _etc_types__WEBPACK_IMPORTED_MODULE_0__["ModelKind"].Bidirectional, + sentence: params['sentence'] || "The girl ran to a local pub to escape the din of her city.", + corpus: params['corpus'] || 'woz', + layer: params['layer'] || 1, + heads: this._initHeads(params['heads']), + threshold: params['threshold'] || 0.7, + tokenInd: params['tokenInd'] || null, + tokenSide: params['tokenSide'] || null, + maskInds: params['maskInds'] || [9], + metaMatch: params['metaMatch'] || "pos", + metaMax: params['metaMax'] || "pos", + displayInspector: params['displayInspector'] || null, + offsetIdxs: this._initOffsetIdxs(params['offsetIdxs']), + hideClsSep: truthy(params['hideClsSep']) || true, + }; + this._token = { side: this._conf.tokenSide, ind: this._conf.tokenInd }; + } + toURL(updateHistory = false) { + _etc_URLHandler__WEBPACK_IMPORTED_MODULE_4__["URLHandler"].updateUrl(this._conf, updateHistory); + } + _initOffsetIdxs(v) { + if (v == null) { + return [-1, 0, 1]; + } + else { + const numberArr = ramda__WEBPACK_IMPORTED_MODULE_3__["map"](toNumber, v); + return numberArr; + } + } + _initHeads(v) { + if (v == null || v.length < 1) { + this.selectAllHeads(); + } + else { + console.log(this.headSet(new Set(v))._conf.heads); + } + return this.heads(); + } + nHeads(val) { + if (val == null) + return this._nHeads; + this._nHeads = val; + return this; + } + nLayers(val) { + if (val == null) + return this._nLayers; + this._nLayers = val; + return this; + } + toggleSelectAllHeads() { + if (this.heads().length == 0) { + this.selectAllHeads(); + } + else { + this.selectNoHeads(); + } + } + selectAllHeads() { + this.headSet(new Set(lodash__WEBPACK_IMPORTED_MODULE_2__["range"](0, this._nHeads))); + } + selectNoHeads() { + this.headSet(new Set([])); + } + toggleHead(head) { + let out; + if (this.headSet().has(head)) { + this.headSet().delete(head); + out = _etc_types__WEBPACK_IMPORTED_MODULE_0__["Toggled"].REMOVED; + } + else { + this.headSet().add(head); + out = _etc_types__WEBPACK_IMPORTED_MODULE_0__["Toggled"].ADDED; + } + // Set through setter function to ensure url is updated + this.headSet(this.headSet()); // I hate mutable datastructures... This is confusing. + return out; + } + toggleToken(e) { + const picker = ramda__WEBPACK_IMPORTED_MODULE_3__["pick"](['ind', 'side']); + const compareEvent = picker(e); + const compareToken = picker(this.token()); + if (ramda__WEBPACK_IMPORTED_MODULE_3__["equals"](compareToken, compareEvent)) { + this.rmToken(); + } + else { + this.token(e); + } + return this; + } + token(val) { + if (val == null) + return this._token; + this._token = val; + this._conf.tokenInd = val.ind; + this._conf.tokenSide = val.side; + this.toURL(); + return this; + } + hasToken() { + const conf = this._conf; + const actuallyNull = ((conf.tokenInd == null) && (conf.tokenSide == null)); + const strNull = (conf.tokenInd == "null"); + return (!actuallyNull) && (!strNull); + } + rmToken() { + this.token({ ind: null, side: null }); + return this; + } + sentence(val) { + if (val == null) + return this._conf.sentence; + this._conf.sentence = val; + this.toURL(true); + return this; + } + threshold(val) { + if (val == null) + return this._conf.threshold; + this._conf.threshold = val; + this.toURL(); + return this; + } + heads() { + return this._conf.heads; + } + layer(val) { + if (val == null) + return this._conf.layer; + this._conf.layer = val; + this.toURL(); + return this; + } + headSet(val) { + if (val == null) { + return this._headSet; + } + this._headSet = val; + this._conf.heads = _etc_Tools__WEBPACK_IMPORTED_MODULE_1__["set2SortedArray"](this._headSet); + this.toURL(); + return this; + } + metaMatch(val) { + if (val == null) + return this._conf.metaMax; + this._conf.metaMax = val; + this.toURL(); + return this; + } + metaMax(val) { + if (val == null) + return this._conf.metaMatch; + this._conf.metaMatch = val; + this.toURL(); + return this; + } + maskInds(val) { + if (val == null) + return this._conf.maskInds; + this._conf.maskInds = val; + this.toURL(); + return this; + } + displayInspector(val) { + if (val == null) + return this._conf.displayInspector; + this._conf.displayInspector = val; + this.toURL(); + return this; + } + offsetIdxs(val) { + if (val == null) + return this._conf.offsetIdxs; + // convert to numbers + this._conf.offsetIdxs = ramda__WEBPACK_IMPORTED_MODULE_3__["map"](toNumber, val); + this.toURL(); + return this; + } + hideClsSep(val) { + if (val == null) + return this._conf.hideClsSep; + this._conf.hideClsSep = truthy(val); + this.toURL(); + return this; + } + model(val) { + if (val == null) + return this._conf.model; + this._conf.model = val; + this.toURL(); + return this; + } + modelKind(val) { + if (val == null) + return this._conf.modelKind; + this._conf.modelKind = val; + this.toURL(); + return this; + } + /** + * Return the offset needed for the modelKind in the configuration + */ + get offset() { + switch (this.modelKind()) { + case _etc_types__WEBPACK_IMPORTED_MODULE_0__["ModelKind"].Bidirectional: { + return 0; + } + case _etc_types__WEBPACK_IMPORTED_MODULE_0__["ModelKind"].Autoregressive: { + return 0; + } + default: { + return 0; + } + } + } + get showNext() { + return this.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_0__["ModelKind"].Autoregressive ? true : false; + } + get matchHistogramDescription() { + return this.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_0__["ModelKind"].Autoregressive ? "Next" : "Matched"; + } + corpus(val) { + if (val == null) + return this._conf.corpus; + this._conf.corpus = val; + this.toURL(); + return this; + } +} + + +/***/ }), + +/***/ "./ts/vis/AttentionConnector.ts": +/*!**************************************!*\ + !*** ./ts/vis/AttentionConnector.ts ***! + \**************************************/ +/*! exports provided: scaleLinearWidth, AttentionGraph */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scaleLinearWidth", function() { return scaleLinearWidth; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttentionGraph", function() { return AttentionGraph; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var d3_selection_multi__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-selection-multi */ "./node_modules/d3-selection-multi/index.js"); +/* harmony import */ var _EdgeConnector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./EdgeConnector */ "./ts/vis/EdgeConnector.ts"); +/* harmony import */ var _VisComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./VisComponent */ "./ts/vis/VisComponent.ts"); +/* harmony import */ var _etc_types__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../etc/types */ "./ts/etc/types.ts"); + + + + + +const scaleLinearWidth = opacity => 5 * opacity ^ 0.33; +class AttentionGraph extends _VisComponent__WEBPACK_IMPORTED_MODULE_3__["VComponent"] { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.css_name = ''; + // OPTIONS WITH DEFAULTS + this._threshold = 0.7; // Accumulation threshold. Between 0-1 + this.options = { + boxheight: 26, + height: 500, + width: 200, + offset: 0, + }; + /** + * Scale the opacity according to the values of the data, from 0 to max of contained data + * Normalize by each source target, or across the whole + */ + this.createScales = () => { + this.opacityScales = []; + let arr = []; + // Group normalization + switch (this.normBy) { + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].Row: + arr = this.edgeData.extent(1); + this.opacityScales = []; + arr.forEach((v, i) => { + this.opacityScales.push(d3__WEBPACK_IMPORTED_MODULE_0__["scaleLinear"]() + .domain([0, v[1]]) + .range([0, 0.9])); + }); + break; + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].Col: + arr = this.edgeData.extent(0); + this.opacityScales = []; + arr.forEach((v, i) => { + this.opacityScales.push(d3__WEBPACK_IMPORTED_MODULE_0__["scaleLinear"]() + .domain([0, v[1]]) + .range([0, 0.9])); + }); + break; + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].All: + const maxIn = d3__WEBPACK_IMPORTED_MODULE_0__["max"](this.plotData.map((d) => d.v)); + for (let i = 0; i < this._data.length; i++) { + this.opacityScales.push(d3__WEBPACK_IMPORTED_MODULE_0__["scaleLinear"]() + .domain([0, maxIn]) + .range([0, 1])); + } + break; + default: + console.log("Nor norming specified"); + break; + } + }; + this.superInitSVG(options); + this._init(); + } + _init() { + this.svg = this.parent; + this.graph = this.svg.selectAll(`.atn-curve`); + this.linkGen = d3__WEBPACK_IMPORTED_MODULE_0__["linkHorizontal"]() + .x(d => d[0]) + .y(d => d[1]); + } + // Define whether to use the 'j' or 'i' attribute to calculate opacities + scaleIdx() { + switch (this.normBy) { + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].Col: + return 'j'; + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].Row: + return 'i'; + case _etc_types__WEBPACK_IMPORTED_MODULE_4__["NormBy"].All: + return 'i'; + } + } + /** + * Create connections between locations of the SVG using D3's linkGen + */ + createConnections() { + const self = this; + const op = this.options; + if (this.paths) { + this.paths.attrs({ + 'd': (d, i) => { + const data = { + source: [0, op.boxheight * (d.i + 0.5 + op.offset)], + target: [op.width, op.boxheight * (d.j + 0.5)] // + 2 allows small offset + }; + return this.linkGen(data); + }, + 'class': 'atn-curve' + }) + .attr("src-idx", (d, i) => d.i) + .attr("target-idx", (d, i) => d.j); + } + } + /** + * Change the height of the SVG + */ + updateHeight() { + const op = this.options; + if (this.svg != null) { + this.svg.attr("height", this.options.height + (op.offset * this.options.boxheight)); + } + return this; + } + /** + * Change the width of the SVG + */ + updateWidth() { + if (this.svg != null) { + this.svg.attr("width", this.options.width); + } + return this; + } + /** + * Change the Opacity of the lines according to the value of the data + */ + updateOpacity() { + const self = this; + if (this.paths != null) { + // paths.transition().duration(500).attr('opacity', (d) => { + this.paths.attr('opacity', (d) => { + const val = this.opacityScales[d[self.scaleIdx()]](d.v); + return val; + }); + this.paths.attr('stroke-width', (d) => { + const val = this.opacityScales[d[self.scaleIdx()]](d.v); + return scaleLinearWidth(val); //5 * val^0.33; + }); + } + return this; + } + /** + * Rerender the graph in the event that the data changes + */ + updateData() { + if (this.graph != null) { + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](".atn-curve").remove(); + const data = this.plotData; + this.paths = this.graph + .data(data) + .join('path'); + this.createConnections(); + this.updateOpacity(); + return this; + } + } + data(value) { + if (value == null) { + return this._data; + } + this._data = value; + this.edgeData = new _EdgeConnector__WEBPACK_IMPORTED_MODULE_2__["EdgeData"](value); + this.plotData = this.edgeData.format(this._threshold); + this.createScales(); + this.updateData(); + return this; + } + height(value) { + if (value == null) { + return this.options.height; + } + this.options.height = value; + this.updateHeight(); + return this; + } + width(value) { + if (value == null) { + return this.options.width; + } + this.options.width = value; + this.updateWidth(); + return this; + } + threshold(value) { + if (value == null) { + return this._threshold; + } + this._threshold = value; + this.plotData = this.edgeData.format(this._threshold); + this.createScales(); + this.updateData(); + return this; + } + _wrangle(data) { + return data; + } + _render(data) { + this.svg.html(''); + this.updateHeight(); + this.updateWidth(); + this.updateData(); + return this; + } +} +AttentionGraph.events = {}; // No events needed for this one + + +/***/ }), + +/***/ "./ts/vis/AttentionHeadBox.ts": +/*!************************************!*\ + !*** ./ts/vis/AttentionHeadBox.ts ***! + \************************************/ +/*! exports provided: getAttentionInfo, AttentionHeadBox */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getAttentionInfo", function() { return getAttentionInfo; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AttentionHeadBox", function() { return AttentionHeadBox; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var _VisComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./VisComponent */ "./ts/vis/VisComponent.ts"); +/* harmony import */ var _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/SVGplus */ "./ts/etc/SVGplus.ts"); +/* harmony import */ var _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tensorflow/tfjs */ "./node_modules/@tensorflow/tfjs/dist/tf.esm.js"); + + + + +/** + * From an attention matrix selected by layer, show a summary of the attentions belonging to each head. + * + * @param headMat The matrix representing all the attentions by head (layer already selected) + * @param headList The heads that are selected + * @param side Is this the right or the left display? + * @param tokenInd If not null, select just the information from a single token across heads + * @returns Information needed to label the headbox + */ +function getAttentionInfo(headMat, headList, side = "left", token = null) { + // Collect only from headlist, average each head, transpose to ease iteration + if (headList.length == 0) { + return { + rows: [[]], + labels: [], + max: 0, + }; + } + let dim = null; + // Only change the attention graph opposite selected token + if (token != null && (token.side != side)) { + dim = token.side == "left" ? -2 : -1; // Assign to "from" direction if "left" + } + let axis = side == "left" ? 2 : 1; + // average across the axis representing the attentions. + let gatheredMat = _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_3__["tensor3d"](headMat); + if (dim != null) { + gatheredMat = gatheredMat.gather([token.ind], dim); + } + let newMat = gatheredMat.gather(headList, 0).mean([axis]).transpose(); + const rowInfo = newMat.arraySync(); + const out = { + rows: rowInfo, + labels: headList, + max: newMat.max().arraySync(), + }; + return out; +} +; +class AttentionHeadBox extends _VisComponent__WEBPACK_IMPORTED_MODULE_1__["VComponent"] { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.css_name = ''; + this.rowCssName = 'att-head'; + this.boxCssName = 'att-rect'; + this._current = {}; + this.options = { + boxDim: 26, + yscale: 1, + xscale: 0.5, + side: "left", + maxWidth: 200, + offset: 0, + }; + this.superInitSVG(options); + this._init(); + } + _init() { + this.headRows = this.base.selectAll(`.${this.rowCssName}`); + this.headCells = this.headRows.selectAll(`${this.boxCssName}`); + this.opacityScale = d3__WEBPACK_IMPORTED_MODULE_0__["scaleLinear"]().range([0, 1]); + } + updateCurrent() { + const op = this.options; + const cur = this._current; + const nHeads = this._data.rows[0].length; + const baseHeadWidth = op.boxDim * op.xscale; + // Scale headwidth according to maximum width + const getHeadScale = (nH) => (Math.min(op.maxWidth / nH, baseHeadWidth) / baseHeadWidth) * op.xscale; + cur.headHeight = op.boxDim * op.yscale; + cur.headWidth = getHeadScale(nHeads) * op.boxDim; + cur.xPad = cur.headWidth; + cur.yPad = (op.boxDim - cur.headHeight) / 2; + const getBoxWidth = (headWidth) => { + const maxBwidth = 100; + const bwidth = this._data.rows[0].length * cur.headWidth; + const scale = d3__WEBPACK_IMPORTED_MODULE_0__["scaleLinear"]; + if (bwidth > maxBwidth) { + return; + } + }; + cur.boxWidth = (this._data.rows[0].length * cur.headWidth); + cur.totalWidth = (2 * cur.xPad) + cur.boxWidth; + cur.totalHeight = (op.boxDim * (this._data.rows.length + op.offset)); + return this._current; + } + updateData() { + const op = this.options; + const self = this; + const boxEvent = (i) => { return { ind: i, side: op.side, head: self._data.labels[i] }; }; + const cur = this.updateCurrent(); + const getBaseX = () => self.base.node().getBoundingClientRect().left; + const getBaseY = () => self.base.node().getBoundingClientRect().top; + this.base.html(''); + this.parent + .attr("width", cur.totalWidth) + .attr("height", cur.totalHeight); + this.headRows = this.base.selectAll(`.${self.rowCssName}`) + .data(self._data.rows) + .join("g") + .attrs({ + class: (d, i) => `${self.rowCssName} ${self.rowCssName}-${i}`, + transform: (d, i) => { + return _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].translate({ + x: cur.xPad, + y: (op.boxDim * (i + op.offset)) + cur.yPad, + }); + }, + width: cur.boxWidth, + height: cur.headHeight, + }) + .on("mouseover", (d, i) => { + self.eventHandler.trigger(AttentionHeadBox.events.rowMouseOver, { ind: i, side: op.side }); + }) + .on("mouseout", (d, i) => { + self.eventHandler.trigger(AttentionHeadBox.events.rowMouseOut, { ind: i, side: op.side }); + }); + this.headCells = this.headRows + .selectAll(`${this.boxCssName}`) + .data(d => d) + .join('rect') + .attrs({ + x: (d, i) => i * cur.headWidth, + y: 0, + class: this.boxCssName, + head: (d, i) => self._data.labels[i], + width: cur.headWidth, + height: cur.headHeight, + opacity: (d) => this.opacityScale(d), + fill: "blue" + }) + .on("mouseover", (d, i) => { + self.eventHandler.trigger(AttentionHeadBox.events.boxMouseOver, boxEvent(i)); + }) + .on("mouseout", (d, i) => { + self.eventHandler.trigger(AttentionHeadBox.events.boxMouseOut, boxEvent(i)); + }) + .on("click", (d, i) => { + self.eventHandler.trigger(AttentionHeadBox.events.boxClick, boxEvent(i)); + }) + .on("mousemove", function (d, i) { + const op = self.options; + const mouse = d3__WEBPACK_IMPORTED_MODULE_0__["mouse"](self.base.node()); + self.eventHandler.trigger(AttentionHeadBox.events.boxMouseMove, { ind: i, side: op.side, baseX: getBaseX(), baseY: getBaseY(), mouse: mouse }); + }) + .append("svg:title") + .text((d, i) => "Head " + (self._data.labels[i] + 1)); + } + _wrangle(data) { + this._data = data; + this.opacityScale = this.opacityScale.domain([0, data.max]); + return data; + } + _render(data) { + this.updateData(); + } +} +AttentionHeadBox.events = { + rowMouseOver: "AttentionHeadBox_RowMouseOver", + rowMouseOut: "AttentionHeadBox_RowMouseOut", + boxMouseOver: "AttentionHeadBox_BoxMouseOver", + boxMouseOut: "AttentionHeadBox_BoxMouseOut", + boxMouseMove: "AttentionHeadBox_BoxMouseMove", + boxClick: "AttentionHeadBox_BoxClick", +}; + + +/***/ }), + +/***/ "./ts/vis/CorpusHistogram.ts": +/*!***********************************!*\ + !*** ./ts/vis/CorpusHistogram.ts ***! + \***********************************/ +/*! exports provided: CorpusHistogram */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CorpusHistogram", function() { return CorpusHistogram; }); +/* harmony import */ var _VisComponent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./VisComponent */ "./ts/vis/VisComponent.ts"); +/* harmony import */ var _etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../etc/SpacyInfo */ "./ts/etc/SpacyInfo.ts"); +/* harmony import */ var _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/SVGplus */ "./ts/etc/SVGplus.ts"); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); + + + + + +/** + * Data formatting functions + */ +const toRenderData = (obj) => Object.keys(obj).map((k, i) => { + return { label: k, count: obj[k] }; +}); +const toStringOrNum = (a) => { + const na = +a; + if (isNaN(na)) { + return a; + } + return na; +}; +const sortByLabel = ramda__WEBPACK_IMPORTED_MODULE_4__["sortBy"](ramda__WEBPACK_IMPORTED_MODULE_4__["compose"](toStringOrNum, ramda__WEBPACK_IMPORTED_MODULE_4__["prop"]('label'))); +const sortByCount = ramda__WEBPACK_IMPORTED_MODULE_4__["sortBy"](ramda__WEBPACK_IMPORTED_MODULE_4__["prop"]('count')); +const toOrderedRender = ramda__WEBPACK_IMPORTED_MODULE_4__["compose"](ramda__WEBPACK_IMPORTED_MODULE_4__["reverse"], +// @ts-ignore -- TODO: fix +sortByCount, toRenderData); +class CorpusHistogram extends _VisComponent__WEBPACK_IMPORTED_MODULE_0__["VComponent"] { + constructor(d3parent, eventHandler, options = {}) { + super(d3parent, eventHandler); + this.css_name = ''; + this._current = { + chart: { + height: null, + width: null + } + }; + this.axes = { + x: d3__WEBPACK_IMPORTED_MODULE_3__["scaleBand"](), + y: d3__WEBPACK_IMPORTED_MODULE_3__["scaleLinear"](), + }; + this.options = { + margin: { + top: 10, + right: 30, + bottom: 50, + left: 40 + }, + barWidth: 25, + width: 185, + height: 230, + val: "pos", + xLabelRot: 45, + xLabelOffset: 15, + yLabelOffset: 5, + }; + this.superInitSVG(); + } + meta(val) { + if (val == null) { + return this.options.val; + } + this.options.val = val; + this.update(this._data); + return this; + } + _init() { } + createXAxis() { + const self = this; + const op = this.options; + const width = op.width - op.margin.left - op.margin.right; + this.axes.x + .domain(ramda__WEBPACK_IMPORTED_MODULE_4__["map"](ramda__WEBPACK_IMPORTED_MODULE_4__["prop"]('label'), self.renderData)) + .rangeRound([0, width]) + .padding(0.1); + this._current.chart.width = width; + } + createYAxis() { + const self = this; + const op = this.options; + const height = op.height - op.margin.top - op.margin.bottom; + this.axes.y + .domain([0, +d3__WEBPACK_IMPORTED_MODULE_3__["max"](ramda__WEBPACK_IMPORTED_MODULE_4__["map"](ramda__WEBPACK_IMPORTED_MODULE_4__["prop"]('count'), self.renderData))]) + .rangeRound([height, 0]); + this._current.chart.height = height; + } + createAxes() { + this.createXAxis(); + this.createYAxis(); + } + _wrangle(data) { + const out = data[this.options.val]; + return toOrderedRender(out); + } + width(val) { + if (val == null) { + return this.options.width; + } + this.options.width = val; + this.updateWidth(); + this.createXAxis(); + return this; + } + height(val) { + if (val == null) { + return this.options.height; + } + this.options.height = val; + this.updateHeight(); + this.createYAxis(); + return this; + } + updateWidth() { + this.svg.attr('width', this.options.width); + } + updateHeight() { + this.svg.attr('height', this.options.height); + } + figWidth(data) { + const op = this.options; + return (data.length * op.barWidth) + op.margin.left + op.margin.right; + } + _render(data) { + const self = this; + const op = this.options; + const curr = this._current; + this.parent.html(''); + this.svg = this.parent; + this.createAxes(); + this.width(this.figWidth(data)); + this.updateHeight(); + // Initialize axes + const g = self.svg.append("g") + .attr("transform", _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].translate({ x: op.margin.left, y: op.margin.top })); + // Hack to allow clearing this histograms to work + self.base = g; + // Fix below for positional changing + const axisBottom = g.append("g") + .attr("transform", _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].translate({ x: 0, y: curr.chart.height })) + .call(d3__WEBPACK_IMPORTED_MODULE_3__["axisBottom"](self.axes.x)); + if (op.val != "offset") { + axisBottom + .selectAll("text") + .attr("y", op.yLabelOffset) // Move below the axis + .attr("x", op.xLabelOffset) // Offset to the right a bit + .attr("transform", _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].rotate(op.xLabelRot)); + } + g.append("g") + .call(d3__WEBPACK_IMPORTED_MODULE_3__["axisLeft"](self.axes.y)); + g.selectAll(".bar") + .data(data) + .join('rect') + .attr("class", "bar") + .attr("x", function (d) { return self.axes.x(d.label); }) + .attr("y", function (d) { return self.axes.y(d.count); }) + .attr("width", self.axes.x.bandwidth()) + .attr("height", function (d) { return curr.chart.height - self.axes.y(d.count); }) + .style('fill', k => _etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_1__["spacyColors"].colorScale[op.val](k.label)); + } +} +CorpusHistogram.events = {}; + + +/***/ }), + +/***/ "./ts/vis/CorpusInspector.ts": +/*!***********************************!*\ + !*** ./ts/vis/CorpusInspector.ts ***! + \***********************************/ +/*! exports provided: CorpusInspector */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CorpusInspector", function() { return CorpusInspector; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var d3_selection_multi__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-selection-multi */ "./node_modules/d3-selection-multi/index.js"); +/* harmony import */ var _VisComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./VisComponent */ "./ts/vis/VisComponent.ts"); +/* harmony import */ var _etc_xd3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../etc/xd3 */ "./ts/etc/xd3.ts"); + + + + +// Helpers +const currMatchIdx = (elem) => +elem.parentNode.getAttribute('matchidx'); +const currRowNum = (elem) => +elem.parentNode.getAttribute('rownum'); +const backgroundColor = x => `rgba(128, 0, 150, ${0.6 * x})`; +class CorpusInspector extends _VisComponent__WEBPACK_IMPORTED_MODULE_2__["VComponent"] { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.css_name = 'corpus-inspector'; + this.options = { + showNext: false + }; + this.scaler = d3__WEBPACK_IMPORTED_MODULE_0__["scalePow"]().range([0, 0.9]).exponent(2); + this.superInitHTML(options); + this._init(); + } + createRows() { + const data = this._data; + this.inspectorRows = this.base.selectAll(".inspector-row") + .data(data) + .join('div') + .classed('inspector-row', true) + .attrs({ + matchIdx: d => d.index, + rowNum: (d, i) => i, + }) + .on("mouseover", (d, i) => { + this.eventHandler.trigger(CorpusInspector.events.rowMouseOver, {}); + }); + } + addTooltip() { + this.inspectorCells = this.inspectorCells + .classed('celltooltip', true) + .append('span') + .classed('tooltiptext', true) + .html((d, i, n) => { + const entityStr = d.is_ent ? "
Entity" : ""; + const att = n[i].parentNode.getAttribute('att').slice(0, 7); + const attStr = `
Attention: ${att}`; + return `POS: ${d.pos.toLowerCase()}
DEP: ${d.dep.toLowerCase()}` + entityStr + attStr; + }); + } + createCells() { + const self = this; + this.inspectorCells = this.inspectorRows.selectAll('.inspector-cell') + .data((d) => d.tokens) + .join('div') + .classed('inspector-cell', true) + .attr('index-offset', (d, i, n) => { + const matchIdx = currMatchIdx(n[i]); + return i - matchIdx; + }) + .attrs({ + pos: d => d.pos.toLowerCase(), + dep: d => d.dep.toLowerCase(), + is_ent: d => d.is_ent + }) + .text(d => d.token.replace("\u0120", " ")) + .classed('matched-cell', d => d.is_match) + .classed('next-cell', function (d) { + return self.showNext() && d.is_next_word; + }) + .classed('gray-cell', function (d, i) { + const idx = +currMatchIdx(this); + return self.showNext() && i > idx; + }); + // Highlight the cells appropriately + this.inspectorCells.each((d, i, n) => { + const idx = currMatchIdx(n[i]); + if (i == idx) { + const att = d.inward; + const maxAtt = +d3__WEBPACK_IMPORTED_MODULE_0__["max"](att); + const currRow = currRowNum(n[i]); + const scaler = self.scaler.domain([0, maxAtt]); + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](`.inspector-row[rownum='${currRow}']`) + .selectAll(`.inspector-cell`) + .style('background', (d, i) => { + return backgroundColor(scaler(att[i])); + }) + .attr('att', (d, i) => att[i]); + } + }); + self.addTooltip(); + } + updateData() { + this.createRows(); + this.createCells(); + } + _init() { } + _wrangle(data) { + this._data = data; + return data; + } + _render(data) { + // Remember that this._data is defined in wrangle which should always be called before render + // as is defined in the update function + this.updateData(); + } + showNext(v) { + if (v == null) + return this.options.showNext; + this.options.showNext = v; + return this; + } +} +CorpusInspector.events = { + rowMouseOver: "CorpusInspector_rowMouseOver", + rowMouseOut: "CorpusInspector_rowMouseOut", + rowClick: "CorpusInspector_rowClick", + rowDblClick: "CorpusInspector_rowDblClick", + cellMouseOver: "CorpusInspector_cellMouseOver", + cellMouseOut: "CorpusInspector_cellMouseOut", + cellClick: "CorpusInspector_cellClick", + cellDblClick: "CorpusInspector_cellDblClick", +}; + + +/***/ }), + +/***/ "./ts/vis/CorpusMatManager.ts": +/*!************************************!*\ + !*** ./ts/vis/CorpusMatManager.ts ***! + \************************************/ +/*! exports provided: CorpusMatManager */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CorpusMatManager", function() { return CorpusMatManager; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _vis_VisComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../vis/VisComponent */ "./ts/vis/VisComponent.ts"); +/* harmony import */ var _etc_SVGplus__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../etc/SVGplus */ "./ts/etc/SVGplus.ts"); +/* harmony import */ var _etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../etc/SpacyInfo */ "./ts/etc/SpacyInfo.ts"); +/* harmony import */ var _etc_xd3__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../etc/xd3 */ "./ts/etc/xd3.ts"); + + + + + + +function managerData2MatData(dataIn, indexOffset = 0, toPick = ['pos']) { + const outOfRangeObj = { + pos: null, + dep: null, + is_ent: null, + token: null, + }; + const chooseProps = ramda__WEBPACK_IMPORTED_MODULE_1__["pick"](toPick); + const dataOut = dataIn.map(d => { + const wordIdx = d.index + indexOffset; + if ((wordIdx < 0) || (wordIdx >= d.tokens.length)) { + return ramda__WEBPACK_IMPORTED_MODULE_1__["assoc"]('height', d.height, outOfRangeObj); + } + const newObj = chooseProps(d.tokens[wordIdx]); + return ramda__WEBPACK_IMPORTED_MODULE_1__["assoc"]('height', d.height, newObj); + }); + return dataOut; +} +class CorpusMatManager extends _vis_VisComponent__WEBPACK_IMPORTED_MODULE_2__["VComponent"] { + // Selections + constructor(d3parent, eventHandler, options = {}) { + super(d3parent, eventHandler); + this.css_name = 'corpus-mat-container'; + this.options = { + cellWidth: 10, + toPick: ['pos'], + idxs: [-1, 0, 1], + divHover: { + width: 60, + height: 40 + } + }; + this._current = {}; + this.rowCssName = 'index-match-results'; + this.cellCssName = 'index-cell-result'; + this.idxs = [-1, 0, 1]; + this.superInitHTML(options); + this._init(); + } + get idxs() { + return this.options.idxs; + } + set idxs(val) { + this.options.idxs = val; + } + // Create static dom elements + _init() { + const self = this; + this.corpusMats = this.base.selectAll('.corpus-mat'); + this.rowGroups = this.corpusMats.selectAll(`.${this.rowCssName}`); + this.divHover = this.base.append('div') + .classed('mat-hover-display', true) + .classed('text-center', true) + .style('width', String(this.options.divHover.width) + 'px') + .style('height', String(this.options.divHover.height) + 'px'); + this.divHover.append('p'); + } + pick(val) { + this.options.toPick = [val]; + this.redraw(); + } + addRight() { + const addedIdx = ramda__WEBPACK_IMPORTED_MODULE_1__["last"](this.idxs) + 1; + this.idxs.push(addedIdx); + this.addCorpusMat(addedIdx, "right"); + } + addLeft() { + const addedIdx = this.idxs[0] - 1; + const addDecrementedHead = x => ramda__WEBPACK_IMPORTED_MODULE_1__["insert"](0, ramda__WEBPACK_IMPORTED_MODULE_1__["head"](x) - 1)(x); + this.idxs = addDecrementedHead(this.idxs); + this.addCorpusMat(addedIdx, "left"); + } + killRight() { + this.kill(Math.max(...this.idxs)); + } + killLeft() { + this.kill(Math.min(...this.idxs)); + } + /** + * Remove edge value from contained indexes + * + * @param d Index to remove + */ + kill(d) { + if (d != 0) { + if (d == Math.min(...this.idxs) || d == Math.max(...this.idxs)) { + this.idxs = ramda__WEBPACK_IMPORTED_MODULE_1__["without"]([d], this.idxs); + this.base.selectAll(`.offset-${d}`).remove(); + } + } + } + _wrangle(data) { + return data; + } + data(val) { + if (val == null) { + return this._data; + } + this._data = val; + this._updateData(); + return this; + } + /** + * The main rendering code, called whenever the data changes. + */ + _updateData() { + const self = this; + const op = this.options; + this.base.selectAll('.corpus-mat').remove(); + this.idxs.forEach((idxOffset, i) => { + self.addCorpusMat(idxOffset); + }); + } + /** + * Add another word's meta information matrix column to either side of the index + * + * @param idxOffset Distance of word from matched word in the sentence + * @param toThe Indicates adding to the "left" or to the "right" of the index + */ + addCorpusMat(idxOffset, toThe = "right") { + const self = this; + const op = this.options; + const boxWidth = op.cellWidth * op.toPick.length; + const boxHeight = ramda__WEBPACK_IMPORTED_MODULE_1__["sum"](ramda__WEBPACK_IMPORTED_MODULE_1__["map"](ramda__WEBPACK_IMPORTED_MODULE_1__["prop"]('height'), this._data)); + let corpusMat; + if (toThe == "right") { + corpusMat = this.base.append('div'); + } + else if (toThe == "left") { + corpusMat = this.base.insert('div', ":first-child"); + } + else { + throw Error("toThe must have argument of 'left' or 'right'"); + } + corpusMat = corpusMat + .data([idxOffset]) + .attr('class', `corpus-mat offset-${idxOffset}`) + .attr('offset', idxOffset) + .append('svg') + .attrs({ + width: boxWidth, + height: boxHeight, + }) + .on('mouseover', function (d, i) { + self.eventHandler.trigger(CorpusMatManager.events.mouseOver, { idx: i, offset: d, val: self.options.toPick[0] }); + }) + .on('mouseout', (d, i) => { + this.eventHandler.trigger(CorpusMatManager.events.mouseOut, { idx: i, offset: d }); + }); + this.addRowGroup(corpusMat); + } + /** + * + * @param mat The base div on which to add matrices and rows + */ + addRowGroup(mat) { + const self = this; + const op = this.options; + const heights = ramda__WEBPACK_IMPORTED_MODULE_1__["map"](ramda__WEBPACK_IMPORTED_MODULE_1__["prop"]('height'), this._data); + const [heightSum, rawHeightList] = ramda__WEBPACK_IMPORTED_MODULE_1__["mapAccum"]((x, y) => [ramda__WEBPACK_IMPORTED_MODULE_1__["add"](x, y), ramda__WEBPACK_IMPORTED_MODULE_1__["add"](x, y)], 0, heights); + const fixList = ramda__WEBPACK_IMPORTED_MODULE_1__["compose"](ramda__WEBPACK_IMPORTED_MODULE_1__["dropLast"](1), + // @ts-ignore + ramda__WEBPACK_IMPORTED_MODULE_1__["prepend"](0)); + const heightList = fixList(rawHeightList); + const rowGroup = mat.selectAll(`.${self.rowCssName}`) + .data(d => managerData2MatData(self._data, d, op.toPick)) + .join("g") + .attr("class", (d, i) => { + return `${self.rowCssName} ${self.rowCssName}-${i}`; + }) + .attr("row-num", (d, i) => i) + .attr("height", d => d.height) + .attr("transform", (d, i) => { + const out = _etc_SVGplus__WEBPACK_IMPORTED_MODULE_3__["SVG"].translate({ + x: 0, + y: heightList[i], + }); + return out; + }); + op.toPick.forEach(prop => { + self.addRect(rowGroup, 0, prop); + }); + } + addRect(g, xShift, prop) { + const self = this; + const op = this.options; + const rects = g.append('rect') + .attrs({ + width: op.cellWidth, + height: d => d.height - 3, + transform: (d, i) => { + return _etc_SVGplus__WEBPACK_IMPORTED_MODULE_3__["SVG"].translate({ + x: xShift, + y: 1.5, + }); + }, + }) + .style('fill', d => CorpusMatManager.colorScale[prop](d[prop])); + const getBaseX = () => self.base.node().getBoundingClientRect().left; + const getBaseY = () => self.base.node().getBoundingClientRect().top; + g.on('mouseover', function (d, i) { + self.divHover.style('visibility', 'visible'); + // Get offset + const col = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this.parentNode.parentNode); // Column + const offset = +col.attr('offset'); + self.eventHandler.trigger(CorpusMatManager.events.rectMouseOver, { idx: i, offset: offset }); + }) + .on('mouseout', function (d, i) { + self.divHover.style('visibility', 'hidden'); + const col = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this.parentNode.parentNode); // Column + const offset = +col.attr('offset'); + self.eventHandler.trigger(CorpusMatManager.events.rectMouseOut, { idx: i, offset: offset }); + }) + .on('mousemove', function (d, i) { + const mouse = d3__WEBPACK_IMPORTED_MODULE_0__["mouse"](self.base.node()); + const divOffset = [3, 3]; + const left = mouse[0] + getBaseX() - (op.divHover.width + divOffset[0]); + const top = mouse[1] + getBaseY() - (op.divHover.height + divOffset[1]); + self.divHover + .style('left', String(left) + 'px') + .style('top', String(top) + 'px') + .selectAll('p') + .text(d[prop]); + }); + } + /** + * @param data Data to display + */ + _render(data) { + this._updateData(); + } +} +CorpusMatManager.events = { + mouseOver: "CorpusMatManager_MouseOver", + mouseOut: "CorpusMatManager_MouseOut", + click: "CorpusMatManager_Click", + dblClick: "CorpusMatManager_DblClick", + rectMouseOver: "CorpusMatManager_RectMouseOver", + rectMouseOut: "CorpusMatManager_RectMouseOut", + rectClick: "CorpusMatManager_RectClick", + rectDblClick: "CorpusMatManager_RectDblClick", +}; +CorpusMatManager.colorScale = _etc_SpacyInfo__WEBPACK_IMPORTED_MODULE_4__["spacyColors"].colorScale; + + +/***/ }), + +/***/ "./ts/vis/EdgeConnector.ts": +/*!*********************************!*\ + !*** ./ts/vis/EdgeConnector.ts ***! + \*********************************/ +/*! exports provided: toEdges, EdgeData */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toEdges", function() { return toEdges; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EdgeData", function() { return EdgeData; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var d3_array__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-array */ "./node_modules/d3-array/src/index.js"); +/* harmony import */ var _etc_arrayUtils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/arrayUtils */ "./ts/etc/arrayUtils.ts"); +/* harmony import */ var _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tensorflow/tfjs */ "./node_modules/@tensorflow/tfjs/dist/tf.esm.js"); + + + + +/** + * Convert data matrix to necessary data array to pass to SVG connections + */ +function toEdges(data, cutoffAmt = 1) { + let outArr = []; + let cutoff; + data.forEach((row, i) => { + cutoff = cutoffAmt * d3__WEBPACK_IMPORTED_MODULE_0__["sum"](row); + let counter = 0; + const sortedArr = _etc_arrayUtils__WEBPACK_IMPORTED_MODULE_2__["sortWithIndices"](row); + sortedArr.arr.forEach((v, j) => { + if (counter < cutoff) { + const obj = { + i: i, + j: sortedArr.sortIndices[j], + v: v, + }; + outArr.push(obj); + counter += v; + } + }); + }); + return outArr; +} +/** + * Class for implementing operations on AttentionGraph implementation. + * Closely tied to [[AttentionConnector]] + */ +class EdgeData { + constructor(data) { + this.data = data; + this.tensData = _tensorflow_tfjs__WEBPACK_IMPORTED_MODULE_3__["tensor"](data); + } + min(axis) { + return this.tensData.min(axis).dataSync(); + } + max(axis) { + return this.tensData.max(axis).dataSync(); + } + extent(axis) { + return d3__WEBPACK_IMPORTED_MODULE_0__["zip"](this.min(axis), this.max(axis)); + } + /** + * Format the data to send to SVG chart. + * + * @param accumulateThresh - A float between 0 and 1, indicating the amount of weight to display. Defaults to 0.7. + */ + format(accumulateThresh = 0.7) { + return toEdges(this.data, accumulateThresh); + } +} + + +/***/ }), + +/***/ "./ts/vis/TextToken.ts": +/*!*****************************!*\ + !*** ./ts/vis/TextToken.ts ***! + \*****************************/ +/*! exports provided: TextTokens, LeftTextToken, RightTextToken */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextTokens", function() { return TextTokens; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LeftTextToken", function() { return LeftTextToken; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RightTextToken", function() { return RightTextToken; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _VisComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./VisComponent */ "./ts/vis/VisComponent.ts"); + + + + +class TextTokens extends _VisComponent__WEBPACK_IMPORTED_MODULE_3__["VComponent"] { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.eInfo = (sel, i) => { return { sel: sel, side: this.side, ind: i }; }; + this.eEmbedding = (sel, i, embed) => { return { sel: sel, side: this.side, ind: i, embeddings: embed }; }; + this.options = { + boxheight: 26, + offset: 0, + divHover: { + width: 150, + height: 150, + offset: [3, 3], + textInfo: "Would predict..." + }, + }; + this.superInitHTML(options); + } + mask(maskInds) { + this.parent.selectAll(`.${this.css_name}`) + .each((d, i, n) => { + const sel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](n[i]); + sel.classed("masked-token", lodash__WEBPACK_IMPORTED_MODULE_2__["includes"](maskInds, i)); + }); + } + getEmbedding(ind) { + return this._data[ind]; + } + _init() { } + _wrangle(data) { + this.data = this._data; + return this._data; + } + _divPlacement() { + const getBaseX = () => self.base.node().getBoundingClientRect().left; + const getBaseY = () => self.base.node().getBoundingClientRect().top; + const self = this; + const op = this.options; + const mouse = d3__WEBPACK_IMPORTED_MODULE_0__["mouse"](self.base.node()); + const divOffset = [3, 3]; + const left = mouse[0] + getBaseX() - (op.divHover.width + divOffset[0]); + const top = mouse[1] + getBaseY() + divOffset[1]; + return [left, top]; + } + _render(data) { + const op = this.options; + const self = this; + // Reset token display + this.base.selectAll("*").remove(); + this.divHover = this.base.append('div') + .classed('tok-info', true) + .classed('mat-hover-display', true) + .classed(this.hover_css_name, true) + .style('width', String(this.options.divHover.width) + 'px') + .style('height', String(this.options.divHover.height) + 'px'); + this.divHover + .append('p') + .classed('p-info', true) + .style('font-weight', 'bold') + .text(op.divHover.textInfo); + // Add blank divs + console.log(`Internal offset (${this.side}): `, op.offset); + const blankDivs = this.base.selectAll(`.blank-text-box`); + blankDivs.data(ramda__WEBPACK_IMPORTED_MODULE_1__["range"](0, op.offset)) + .join("div") + .classed("blank-text-box", true) + .classed("token", true) + .style("height", op.boxheight + 'px') + .text((d) => " "); + // Render normal text box data + self.textBoxes = this.base.selectAll(`.${this.css_name}`) + .data(data) + .join("div") + .attr("class", (d, i) => `token ${this.css_name} token-${i}`) + .attr("id", (d, i) => `${this.css_name}-${i}`) + .style('height', op.boxheight + 'px') + .text((d) => { + return d.text.replace("\u0120", " ").replace("\u010A", "\\n"); + }) + .on('mouseover', function (d, i) { + const sel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + sel.style('background', 'lightblue'); + self.eventHandler.trigger(TextTokens.events.tokenMouseOver, self.eInfo(sel, i)); + self.divHover.style('visibility', 'visible'); + }) + .on('mouseout', function (d, i) { + let sel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + sel.style('background', 0); + self.eventHandler.trigger(TextTokens.events.tokenMouseOut, self.eInfo(sel, i)); + self.divHover.style('visibility', 'hidden'); + }) + .on('mousemove', function (d, i) { + const s = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + const [left, top] = self._divPlacement(); + self.divHover + .style('left', String(left) + 'px') + .style('top', String(top) + 'px') + .selectAll(".topk-word-box") + //@ts-ignore + .data(d3__WEBPACK_IMPORTED_MODULE_0__["zip"](d.topk_words, d.topk_probs)) + .join('p') + .classed("topk-word-box", true) + .text(w => { + const name = w[0].replace(/\u0120/g, " ").replace(/\u010A/g, "\\n"); + const prob = w[1].toFixed(2); + return name + ": " + prob; + }); + }); + self.addClick(self.textBoxes); + } + addClick(textboxes) { + const self = this; + self.textBoxes = textboxes + .on('click', (d, i, n) => { + const sel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](n[i]); + self.eventHandler.trigger(TextTokens.events.tokenClick, self.eEmbedding(sel, i, d.embeddings)); + }) + .on('dblclick', (d, i, n) => { + const sel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](n[i]); + self.eventHandler.trigger(TextTokens.events.tokenDblClick, self.eInfo(sel, i)); + }); + } +} +TextTokens.events = { + tokenMouseOver: "TextToken_TokenMouseOver", + tokenMouseOut: "TextToken_TokenMouseOut", + tokenClick: "TextToken_TokenClick", + tokenDblClick: "TextToken_TokenDblClick", +}; +class LeftTextToken extends TextTokens { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.css_name = 'left-token'; + this.hover_css_name = 'left-token-hover'; + this.side = 'left'; + this.offset = 1; + } +} +class RightTextToken extends TextTokens { + constructor(d3Parent, eventHandler, options = {}) { + super(d3Parent, eventHandler); + this.css_name = 'right-token'; + this.hover_css_name = 'right-token-hover'; + this.side = 'right'; + this.offset = 0; + } + _divPlacement() { + const getBaseX = () => self.base.node().getBoundingClientRect().left; + const getBaseY = () => self.base.node().getBoundingClientRect().top; + const self = this; + const op = this.options; + const mouse = d3__WEBPACK_IMPORTED_MODULE_0__["mouse"](self.base.node()); + const divOffset = [3, 3]; + const left = mouse[0] + getBaseX() + divOffset[0]; + const top = mouse[1] + getBaseY() + divOffset[1]; + return [left, top]; + } +} + + +/***/ }), + +/***/ "./ts/vis/VisComponent.ts": +/*!********************************!*\ + !*** ./ts/vis/VisComponent.ts ***! + \********************************/ +/*! exports provided: VComponent */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VComponent", function() { return VComponent; }); +/* harmony import */ var _etc_Util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../etc/Util */ "./ts/etc/Util.ts"); +/* harmony import */ var _etc_SimpleEventHandler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../etc/SimpleEventHandler */ "./ts/etc/SimpleEventHandler.ts"); +/* harmony import */ var _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../etc/SVGplus */ "./ts/etc/SVGplus.ts"); + + + +/** + * Should have VComponentHTML and VComponentSVG + * + * Common Properties: + * - events + * - eventHandler (V important) + * - options (Maintains public state. Can expose these with get/set functions with auto update) + * - _current (Maintains private state) + * - cssName (synced with corresponding CSS file) + * - parent (HTML is div containing the base, SVG is SVG element) + * - base (HTML is div with css_name established) + * - _data (Data used to create and render the component) + * - _renderData (Data needed to display. This may not be needed, but is currently used in histogram) + * + * Common Methods: + * - constructor + * - _render() Consider replacing with `_updateData()` that updates all data at once + * - update() Consider replacing this with `data()` that auto updates data + * - redraw() + * - destroy() + */ +class VComponent { + // CONSTRUCTOR ============================================================ + /** + * Simple constructor. Subclasses should call @superInit(options) as well. + * see why here: https://stackoverflow.com/questions/43595943/why-are-derived-class-property-values-not-seen-in-the-base-class-constructor + * + * template: + constructor(d3Parent: D3Sel, eventHandler?: SimpleEventHandler, options: {} = {}) { + super(d3Parent, eventHandler); + // -- access to subclass params: + this.superInit(options); + } + * + * @param {D3Sel} d3parent D3 selection of parent SVG DOM Element + * @param {SimpleEventHandler} eventHandler a global event handler object or 'null' for local event handler + */ + constructor(d3parent, eventHandler) { + this.id = _etc_Util__WEBPACK_IMPORTED_MODULE_0__["Util"].simpleUId({}); + this.parent = d3parent; + // If not further specified - create a local event handler bound to the bas element + this.eventHandler = eventHandler || + new _etc_SimpleEventHandler__WEBPACK_IMPORTED_MODULE_1__["SimpleEventHandler"](this.parent.node()); + // Object for storing internal states and variables + this._visibility = { hidden: false }; + } + superInitHTML(options = {}) { + Object.keys(options).forEach(key => this.options[key] = options[key]); + this.base = this.parent.append('div') + .classed(this.css_name, true); + } + /** + * Has to be called as last call in subclass constructor. + * + * @param {{}} options + * @param defaultLayers -- create the default layers: bg -> main -> fg + */ + superInitSVG(options = {}, defaultLayers = ['bg', 'main', 'fg']) { + // Set default options if not specified in constructor call + // const defaults = this.defaultOptions; + // this.options = {}; + // const keys = new Set([...Object.keys(defaults), ...Object.keys(options)]); + // keys.forEach(key => this.options[key] = (key in options) ? options[key] : defaults[key]); + Object.keys(options).forEach(key => this.options[key] = options[key]); + this.layers = {}; + // Create the base group element + const svg = this.parent; + this.base = _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].group(svg, this.css_name + ' ID' + this.id, this.options.pos); + // create default layers: background, main, foreground + if (defaultLayers) { + // construction order is important ! + defaultLayers.forEach(layer => { + this.layers[layer] = _etc_SVGplus__WEBPACK_IMPORTED_MODULE_2__["SVG"].group(this.base, layer); + }); + } + } + // DATA UPDATE & RENDER ============================================================ + /** + * Every time data has changed, update is called and + * triggers wrangling and re-rendering + * @param {Object} data data object + * @return {*} --- + */ + update(data) { + this._data = data; + if (this._visibility.hidden) + return; + this.renderData = this._wrangle(data); + this._render(this.renderData); + } + // UPDATE OPTIONS ============================================================ + /** + * Updates instance options + * @param {Object} options only the options that should be updated + * @param {Boolean} reRender if option change requires a re-rendering (default:false) + * @returns {*} --- + */ + updateOptions({ options, reRender = false }) { + Object.keys(options).forEach(k => this.options[k] = options[k]); + if (reRender) + this._render(this.renderData); + } + // === CONVENIENCE ==== + redraw() { + this._render(this.renderData); + } + setHideElement(hE) { + this._visibility.hideElement = hE; + } + hideView() { + if (!this._visibility.hidden) { + const hE = this._visibility.hideElement || this.parent; + hE.transition().styles({ + 'opacity': 0, + 'pointer-events': 'none' + }).style('display', 'none'); + this._visibility.hidden = true; + } + } + unhideView() { + if (this._visibility.hidden) { + const hE = this._visibility.hideElement || this.parent; + hE.transition().styles({ + 'opacity': 1, + 'pointer-events': null, + 'display': null + }); + this._visibility.hidden = false; + // this.update(this.data); + } + } + destroy() { + this.base.remove(); + } + clear() { + this.base.html(''); + } +} +// STATIC FIELDS ============================================================ +/** + * The static property that contains all class related events. + * Should be overwritten and event strings have to be unique!! + */ +VComponent.events = { noEvent: 'VComponent_noEvent' }; + + +/***/ }), + +/***/ "./ts/vis/myMain.ts": +/*!**************************!*\ + !*** ./ts/vis/myMain.ts ***! + \**************************/ +/*! exports provided: MainGraphic */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MainGraphic", function() { return MainGraphic; }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ "./node_modules/d3/index.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js"); +/* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ramda */ "./node_modules/ramda/es/index.js"); +/* harmony import */ var _etc_types__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../etc/types */ "./ts/etc/types.ts"); +/* harmony import */ var _etc_xd3__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../etc/xd3 */ "./ts/etc/xd3.ts"); +/* harmony import */ var _api_mainApi__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../api/mainApi */ "./ts/api/mainApi.ts"); +/* harmony import */ var _uiConfig__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../uiConfig */ "./ts/uiConfig.ts"); +/* harmony import */ var _TextToken__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./TextToken */ "./ts/vis/TextToken.ts"); +/* harmony import */ var _AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./AttentionHeadBox */ "./ts/vis/AttentionHeadBox.ts"); +/* harmony import */ var _AttentionConnector__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./AttentionConnector */ "./ts/vis/AttentionConnector.ts"); +/* harmony import */ var _CorpusInspector__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./CorpusInspector */ "./ts/vis/CorpusInspector.ts"); +/* harmony import */ var _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../data/TokenWrapper */ "./ts/data/TokenWrapper.ts"); +/* harmony import */ var _data_AttentionCapsule__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../data/AttentionCapsule */ "./ts/data/AttentionCapsule.ts"); +/* harmony import */ var _etc_SimpleEventHandler__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../etc/SimpleEventHandler */ "./ts/etc/SimpleEventHandler.ts"); +/* harmony import */ var _vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../vis/CorpusMatManager */ "./ts/vis/CorpusMatManager.ts"); +/* harmony import */ var _vis_CorpusHistogram__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../vis/CorpusHistogram */ "./ts/vis/CorpusHistogram.ts"); +/* harmony import */ var _data_FaissSearchWrapper__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../data/FaissSearchWrapper */ "./ts/data/FaissSearchWrapper.ts"); +/* harmony import */ var _etc_Util__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../etc/Util */ "./ts/etc/Util.ts"); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs */ "./node_modules/rxjs/_esm5/index.js"); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs/operators */ "./node_modules/rxjs/_esm5/operators/index.js"); + + + + + + + + + + + + + + + + + + + + +function isNullToken(tok) { + const isSomeNull = x => { + return (x == null) || (x == "null"); + }; + const tokIsNull = tok == null; + const tokHasNull = isSomeNull(tok.side) || isSomeNull(tok.ind); + return tokIsNull || tokHasNull; +} +function showBySide(e) { + // Check if saved token in uiConf is null + if (!isNullToken(e)) { + const classSelector = e.side == "left" ? "src-idx" : "target-idx"; + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].setHidden(".atn-curve"); + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].setVisible(`.atn-curve[${classSelector}='${e.ind}']`); + } +} +function chooseShowBySide(savedEvent, newEvent) { + if (isNullToken(savedEvent)) { + showBySide(newEvent); + } +} +function chooseShowAll(savedEvent) { + if (isNullToken(savedEvent)) + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].setVisible(".atn-curve"); +} +function unselectHead(head) { + const affectedHeads = d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](`.att-rect[head='${head}']`); + affectedHeads.classed("unselected", true); +} +function selectHead(head) { + const affectedHeads = d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"](`.att-rect[head='${head}']`); + affectedHeads.classed("unselected", false); +} +function setSelDisabled(attr, sel) { + const val = attr ? true : null; + sel.attr('disabled', val); +} +class MainGraphic { + constructor() { + this.api = new _api_mainApi__WEBPACK_IMPORTED_MODULE_5__["API"](); + this.uiConf = new _uiConfig__WEBPACK_IMPORTED_MODULE_6__["UIConfig"](); + this.skeletonInit(); + this.mainInit(); + } + /** + * Functions that can be called without any information of a response. + * + * This should be called once and only once + */ + skeletonInit() { + this.sels = { + body: d3__WEBPACK_IMPORTED_MODULE_0__["select"]('body'), + atnContainer: d3__WEBPACK_IMPORTED_MODULE_0__["select"]('#atn-container'), + atnDisplay: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#atn-display"), + modelSelector: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#model-option-selector"), + corpusSelector: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#corpus-select"), + atnHeads: { + left: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#left-att-heads"), + right: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#right-att-heads"), + headInfo: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#head-info-box") + .classed('mat-hover-display', true) + .classed('text-center', true) + .style('width', String(70) + 'px') + .style('height', String(30) + 'px') + .style('visibillity', 'hidden') + }, + form: { + sentenceA: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#form-sentence-a"), + button: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#update-sentence"), + }, + tokens: { + left: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#left-tokens"), + right: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#right-tokens"), + }, + clsToggle: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#cls-toggle").select(".switch"), + layerCheckboxes: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#layer-select"), + headCheckboxes: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#head-select"), + contextQuery: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#search-contexts"), + embeddingQuery: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#search-embeddings"), + selectedHeads: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#selected-heads"), + headSelectAll: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#select-all-heads"), + headSelectNone: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#select-no-heads"), + testCheckbox: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#simple-embed-query"), + threshSlider: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#my-range"), + corpusInspector: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#corpus-similar-sentences-div"), + corpusMatManager: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#corpus-mat-container"), + corpusMsgBox: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#corpus-msg-box"), + histograms: { + matchedWordDescription: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#match-kind"), + matchedWord: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#matched-histogram-container"), + maxAtt: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#max-att-histogram-container"), + }, + buttons: { + killLeft: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#kill-left"), + addLeft: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#minus-left"), + addRight: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#plus-right"), + killRight: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#kill-right"), + refresh: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#mat-refresh") + }, + metaSelector: { + matchedWord: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#matched-meta-select"), + maxAtt: d3__WEBPACK_IMPORTED_MODULE_0__["select"]("#max-att-meta-select") + } + }; + this.eventHandler = new _etc_SimpleEventHandler__WEBPACK_IMPORTED_MODULE_13__["SimpleEventHandler"](this.sels.body.node()); + this.vizs = { + leftHeads: new _AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"](this.sels.atnHeads.left, this.eventHandler, { side: "left", }), + rightHeads: new _AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"](this.sels.atnHeads.right, this.eventHandler, { side: "right" }), + tokens: { + left: new _TextToken__WEBPACK_IMPORTED_MODULE_7__["LeftTextToken"](this.sels.tokens.left, this.eventHandler), + right: new _TextToken__WEBPACK_IMPORTED_MODULE_7__["RightTextToken"](this.sels.tokens.right, this.eventHandler), + }, + attentionSvg: new _AttentionConnector__WEBPACK_IMPORTED_MODULE_9__["AttentionGraph"](this.sels.atnDisplay, this.eventHandler), + corpusInspector: new _CorpusInspector__WEBPACK_IMPORTED_MODULE_10__["CorpusInspector"](this.sels.corpusInspector, this.eventHandler), + corpusMatManager: new _vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__["CorpusMatManager"](this.sels.corpusMatManager, this.eventHandler, { idxs: this.uiConf.offsetIdxs() }), + histograms: { + matchedWord: new _vis_CorpusHistogram__WEBPACK_IMPORTED_MODULE_15__["CorpusHistogram"](this.sels.histograms.matchedWord, this.eventHandler), + maxAtt: new _vis_CorpusHistogram__WEBPACK_IMPORTED_MODULE_15__["CorpusHistogram"](this.sels.histograms.maxAtt, this.eventHandler), + }, + }; + this._bindEventHandler(); + } + mainInit() { + const self = this; + this.sels.body.style("cursor", "progress"); + this.api.getModelDetails(this.uiConf.model()).then(md => { + const val = md.payload; + this.uiConf.nLayers(val.nlayers).nHeads(val.nheads); + this.initLayers(this.uiConf.nLayers()); + this.api.getMetaAttentions(this.uiConf.model(), this.uiConf.sentence(), this.uiConf.layer()).then(attention => { + const att = attention.payload; + this.initFromResponse(att); + // Wrap postInit into function so asynchronous call does not mess with necessary inits + const postResponseDisplayCleanup = () => { + this._toggleTokenSel(); + const toDisplay = this.uiConf.displayInspector(); + this._searchDisabler(); + if (toDisplay == 'context') { + this._queryContext(); + } + else if (toDisplay == 'embeddings') { + this._queryEmbeddings(); + } + }; + let normBy; + if ((this.uiConf.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive) && (!this.uiConf.hideClsSep())) { + normBy = _etc_types__WEBPACK_IMPORTED_MODULE_3__["NormBy"].Col; + } + else { + normBy = _etc_types__WEBPACK_IMPORTED_MODULE_3__["NormBy"].All; + } + this.vizs.attentionSvg.normBy = normBy; + if (this.uiConf.maskInds().length > 0) { + this.tokCapsule.a.maskInds = this.uiConf.maskInds(); + this.api.updateMaskedAttentions(this.uiConf.model(), this.tokCapsule.a, this.uiConf.sentence(), this.uiConf.layer()).then(resp => { + const r = resp.payload; + this.attCapsule.updateFromNormal(r, this.uiConf.hideClsSep()); + this.tokCapsule.updateTokens(r); + this.update(); + postResponseDisplayCleanup(); + }); + } + else { + this.update(); + postResponseDisplayCleanup(); + } + if (this.uiConf.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive) { + // Ensure only 1 mask ind is present for autoregressive models + if (this.uiConf.hasToken()) { + this.grayToggle(this.uiConf.token().ind); + } + self.vizs.tokens.left.options.divHover.textInfo = "Would predict next..."; + self.vizs.tokens.right.options.divHover.textInfo = "Would predict next..."; + } + else { + self.vizs.tokens.left.options.divHover.textInfo = "Would predict here..."; + self.vizs.tokens.right.options.divHover.textInfo = "Would predict here..."; + } + this.sels.body.style("cursor", "default"); + }); + }); + } + initFromResponse(attention) { + this.attCapsule = Object(_data_AttentionCapsule__WEBPACK_IMPORTED_MODULE_12__["makeFromMetaResponse"])(attention, this.uiConf.hideClsSep()); + this.tokCapsule = new _data_TokenWrapper__WEBPACK_IMPORTED_MODULE_11__["TokenWrapper"](attention); + this._staticInits(); + } + leaveCorpusMsg(msg) { + this.vizs.corpusInspector.hideView(); + this.vizs.corpusMatManager.hideView(); + console.log("Running leave msg"); + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].unhideElement(this.sels.corpusMsgBox); + this.sels.corpusMsgBox.text(msg); + } + _bindEventHandler() { + const self = this; + this.eventHandler.bind(_TextToken__WEBPACK_IMPORTED_MODULE_7__["TextTokens"].events.tokenDblClick, (e) => { + switch (self.uiConf.modelKind()) { + case _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Bidirectional: { + e.sel.classed("masked-token", !e.sel.classed("masked-token")); + const letter = Object(_data_TokenWrapper__WEBPACK_IMPORTED_MODULE_11__["sideToLetter"])(e.side, this.uiConf.attType); + self.tokCapsule[letter].toggle(e.ind); + self.sels.body.style("cursor", "progress"); + self.api.updateMaskedAttentions(this.uiConf.model(), this.tokCapsule.a, this.uiConf.sentence(), this.uiConf.layer()).then((resp) => { + const r = resp.payload; + self.attCapsule.updateFromNormal(r, this.uiConf.hideClsSep()); + self.tokCapsule.updateTokens(r); + self.uiConf.maskInds(this.tokCapsule.a.maskInds); + self.update(); + self.sels.body.style("cursor", "default"); + }); + break; + } + case _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive: { + console.log("Autoregressive model doesn't do masking"); + break; + } + default: { + console.log("What kind of model is this?"); + break; + } + } + }); + this.eventHandler.bind(_TextToken__WEBPACK_IMPORTED_MODULE_7__["TextTokens"].events.tokenMouseOver, (e) => { + chooseShowBySide(this.uiConf.token(), e); + }); + this.eventHandler.bind(_TextToken__WEBPACK_IMPORTED_MODULE_7__["TextTokens"].events.tokenMouseOut, (e) => { + chooseShowAll(this.uiConf.token()); + }); + this.eventHandler.bind(_TextToken__WEBPACK_IMPORTED_MODULE_7__["TextTokens"].events.tokenClick, (e) => { + const tokToggle = () => { + this.uiConf.toggleToken(e); + this._toggleTokenSel(); + showBySide(e); + }; + tokToggle(); + this.renderAttHead(); + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.rowMouseOver, (e) => { + self.sels.atnHeads.headInfo.style('visibility', 'visible'); + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.rowMouseOut, () => { + self.sels.atnHeads.headInfo.style('visibility', 'hidden'); + // Don't do anything special on row mouse out + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.boxMouseOver, (e) => { + const updateMat = this.attCapsule.byHead(e.head); + this.vizs.attentionSvg.data(updateMat); + this.vizs.attentionSvg.update(updateMat); + showBySide(this.uiConf.token()); + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.boxMouseOut, () => { + const att = this.attCapsule.byHeads(this.uiConf.heads()); + this.vizs.attentionSvg.data(att); + this.vizs.attentionSvg.update(att); + showBySide(this.uiConf.token()); + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.boxMouseMove, (e) => { + const headInfo = self.sels.atnHeads.headInfo; + let left, top, borderRadius; + if (e.side == "left") { + const divOffset = [12, 3]; + left = e.mouse[0] + e.baseX - (+headInfo.style('width').replace('px', '') + divOffset[0]); + top = e.mouse[1] + e.baseY - (+headInfo.style('height').replace('px', '') + divOffset[1]); + borderRadius = "8px 8px 1px 8px"; + } + else { + const divOffset = [-13, 3]; + left = e.mouse[0] + e.baseX + divOffset[0]; + top = e.mouse[1] + e.baseY - (+headInfo.style('height').replace('px', '') + divOffset[1]); + borderRadius = "8px 8px 8px 1px"; + } + headInfo + .style('visibility', 'visible') + .style('left', String(left) + 'px') + .style('top', String(top) + 'px') + .style('border-radius', borderRadius) + .text(`Head: ${e.ind + 1}`); + // Don't do anything special on row mouse over + }); + this.eventHandler.bind(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["AttentionHeadBox"].events.boxClick, (e) => { + const result = this.uiConf.toggleHead(e.head); + if (result == _etc_types__WEBPACK_IMPORTED_MODULE_3__["Toggled"].ADDED) { + selectHead(e.head); + } + else if (result == _etc_types__WEBPACK_IMPORTED_MODULE_3__["Toggled"].REMOVED) { + unselectHead(e.head); + } + this._searchDisabler(); + this._renderHeadSummary(); + this.renderSvg(); + }); + this.eventHandler.bind(_vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__["CorpusMatManager"].events.mouseOver, (e) => { + // Uncomment the below if you want to modify the whole column + // const selector = `.inspector-cell[index-offset='${e.offset}']` + // d3.selectAll(selector).classed("hovered-col", true) + }); + this.eventHandler.bind(_vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__["CorpusMatManager"].events.mouseOut, (e) => { + // Uncomment the below if you want to modify the whole column + // const selector = `.inspector-cell[index-offset='${e.offset}']` + // d3.selectAll(selector).classed("hovered-col", false) + }); + this.eventHandler.bind(_vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__["CorpusMatManager"].events.rectMouseOver, (e) => { + const row = d3__WEBPACK_IMPORTED_MODULE_0__["select"](`.inspector-row[rownum='${e.idx}']`); + const word = row.select(`.inspector-cell[index-offset='${e.offset}']`); + word.classed("hovered-col", true); + }); + this.eventHandler.bind(_vis_CorpusMatManager__WEBPACK_IMPORTED_MODULE_14__["CorpusMatManager"].events.rectMouseOut, (e) => { + const row = d3__WEBPACK_IMPORTED_MODULE_0__["select"](`.inspector-row[rownum='${e.idx}']`); + const word = row.select(`.inspector-cell[index-offset='${e.offset}']`); + word.classed("hovered-col", false); + }); + } + _toggleTokenSel() { + const e = this.uiConf.token(); + const alreadySelected = d3__WEBPACK_IMPORTED_MODULE_0__["select"]('.selected-token'); + // If no token should be selected, unselect all tokens + if (!this.uiConf.hasToken()) { + const newSel = d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.selected-token'); + if (!newSel.empty()) + newSel.classed('selected-token', false); + } + // Otherwise, select the indicated token + else { + const token2String = (e) => `#${e.side}-token-${e.ind}`; + const newSel = d3__WEBPACK_IMPORTED_MODULE_0__["select"](token2String(e)); + // Check that selection exists + if (!newSel.empty()) + newSel.classed('selected-token', true); + } + // Remove previous token selection, if any + if (!alreadySelected.empty()) { + alreadySelected.classed('selected-token', false); + } + if (this.uiConf.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive) { + this.grayToggle(+e.ind); + this.markNextToggle(+e.ind, this.tokCapsule.a.length()); + } + this._searchDisabler(); + } + /** Gray all tokens that have index greater than ind */ + grayBadToks(ind) { + if (this.uiConf.modelKind() == _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive) { + const grayToks = function (d, i) { + const s = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + s.classed("masked-token", i > ind); + }; + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.right-token').each(grayToks); + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.left-token').each(grayToks); + } + } + grayToggle(ind) { + if (this.uiConf.hasToken()) + this.grayBadToks(ind); + else + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.token').classed('masked-token', false); + } + markNextWordToks(ind, N) { + const markToks = function (d, i) { + const s = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + s.classed("next-token", i == Math.min(ind + 1, N)); + }; + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.right-token').each(markToks); + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.left-token').each(markToks); + } + markNextToggle(ind, N) { + if (this.uiConf.hasToken()) + this.markNextWordToks(ind, N); + else + d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.token').classed('next-token', false); + } + _initModelSelection() { + const self = this; + // Below are the available models. Will need to choose 3 to be available ONLY + const data = [ + { name: "bert-base-cased", kind: _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Bidirectional }, + { name: "bert-base-uncased", kind: _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Bidirectional }, + { name: "distilbert-base-uncased", kind: _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Bidirectional }, + { name: "distilroberta-base", kind: _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Bidirectional }, + // { name: "roberta-base", kind: tp.ModelKind.Bidirectional }, + { name: "gpt2", kind: _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive }, + ]; + const names = ramda__WEBPACK_IMPORTED_MODULE_2__["map"](ramda__WEBPACK_IMPORTED_MODULE_2__["prop"]('name'))(data); + const kinds = ramda__WEBPACK_IMPORTED_MODULE_2__["map"](ramda__WEBPACK_IMPORTED_MODULE_2__["prop"]('kind'))(data); + const kindmap = ramda__WEBPACK_IMPORTED_MODULE_2__["zipObj"](names, kinds); + this.sels.modelSelector.selectAll('.model-option') + .data(data) + .join('option') + .classed('model-option', true) + .property('value', d => d.name) + .attr("modelkind", d => d.kind) + .text(d => d.name); + this.sels.modelSelector.property('value', this.uiConf.model()); + this.sels.modelSelector.on('change', function () { + const me = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + const mname = me.property('value'); + self.uiConf.model(mname); + self.uiConf.modelKind(kindmap[mname]); + if (kindmap[mname] == _etc_types__WEBPACK_IMPORTED_MODULE_3__["ModelKind"].Autoregressive) { + console.log("RESETTING MASK INDS"); + self.uiConf.maskInds([]); + } + self.mainInit(); + }); + } + _initCorpusSelection() { + const data = [ + { code: "woz", display: "Wizard of Oz" }, + { code: "wiki", display: "Wikipedia" }, + ]; + const self = this; + self.sels.corpusSelector.selectAll('option') + .data(data) + .join('option') + .property('value', d => d.code) + .text(d => d.display); + this.sels.corpusSelector.on('change', function () { + const me = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this); + self.uiConf.corpus(me.property('value')); + console.log(self.uiConf.corpus()); + }); + } + _staticInits() { + this._initSentenceForm(); + this._initModelSelection(); + this._initCorpusSelection(); + this._initQueryForm(); + this._initAdder(); + this._renderHeadSummary(); + this._initMetaSelectors(); + this._initToggle(); + this.renderAttHead(); + this.renderTokens(); + } + _initAdder() { + const updateUrlOffsetIdxs = () => { + this.uiConf.offsetIdxs(this.vizs.corpusMatManager.idxs); + }; + const fixCorpusMatHeights = () => { + const newWrapped = this._wrapResults(this.vizs.corpusMatManager.data()); + this.vizs.corpusMatManager.data(newWrapped.data); + updateUrlOffsetIdxs(); + }; + this.sels.buttons.addRight.on('click', () => { + this.vizs.corpusMatManager.addRight(); + updateUrlOffsetIdxs(); + }); + this.sels.buttons.addLeft.on('click', () => { + this.vizs.corpusMatManager.addLeft(); + updateUrlOffsetIdxs(); + }); + this.sels.buttons.killRight.on('click', () => { + this.vizs.corpusMatManager.killRight(); + updateUrlOffsetIdxs(); + }); + this.sels.buttons.killLeft.on('click', () => { + this.vizs.corpusMatManager.killLeft(); + updateUrlOffsetIdxs(); + }); + this.sels.buttons.refresh.on('click', () => { + fixCorpusMatHeights(); + }); + const onresize = () => { + if (this.sels.corpusInspector.text() != '') + fixCorpusMatHeights(); + }; + window.onresize = onresize; + } + _initMetaSelectors() { + this._initMatchedWordSelector(this.sels.metaSelector.matchedWord); + this._initMaxAttSelector(this.sels.metaSelector.maxAtt); + } + _initMaxAttSelector(sel) { + const self = this; + const chooseSelected = (value) => { + const ms = sel.selectAll('label'); + ms.classed('active', false); + const el = sel.selectAll(`label[value=${value}]`); + el.classed('active', true); + }; + chooseSelected(this.uiConf.metaMax()); + const el = sel.selectAll('label'); + el.on('click', function () { + const val = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this).attr('value'); + // Do toggle + sel.selectAll('.active').classed('active', false); + d3__WEBPACK_IMPORTED_MODULE_0__["select"](this).classed('active', true); + self.uiConf.metaMax(val); + self.vizs.histograms.maxAtt.meta(val); + }); + } + _initMatchedWordSelector(sel) { + const self = this; + const chooseSelected = (value) => { + const ms = sel.selectAll('label'); + ms.classed('active', false); + const el = sel.selectAll(`label[value=${value}]`); + el.classed('active', true); + }; + chooseSelected(this.uiConf.metaMatch()); + const el = sel.selectAll('label'); + el.on('click', function () { + const val = d3__WEBPACK_IMPORTED_MODULE_0__["select"](this).attr('value'); + // Do toggle + sel.selectAll('.active').classed('active', false); + d3__WEBPACK_IMPORTED_MODULE_0__["select"](this).classed('active', true); + self.uiConf.metaMatch(val); + self._updateCorpusInspectorFromMeta(val); + }); + } + _disableSearching(attr) { + setSelDisabled(attr, this.sels.contextQuery); + setSelDisabled(attr, this.sels.embeddingQuery); + } + _updateCorpusInspectorFromMeta(val) { + this.vizs.corpusInspector.showNext(this.uiConf.showNext); + this.vizs.corpusMatManager.pick(val); + this.vizs.histograms.matchedWord.meta(val); + } + _initSentenceForm() { + const self = this; + this.sels.form.sentenceA.attr('placeholder', "Enter new sentence to analyze"); + this.sels.form.sentenceA.attr('value', this.uiConf.sentence()); + const clearInspector = () => { + self.vizs.corpusMatManager.clear(); + self.vizs.corpusInspector.clear(); + self.vizs.histograms.matchedWord.clear(); + self.vizs.histograms.maxAtt.clear(); + }; + const submitNewSentence = () => { + // replace all occurences of '#' in sentence as this causes the API to break + const sentence_a = this.sels.form.sentenceA.property("value").replace(/\#/g, ''); + // Only update if the form is filled correctly + if (sentence_a.length) { + this.sels.body.style("cursor", "progress"); + this.api.getMetaAttentions(this.uiConf.model(), sentence_a, this.uiConf.layer()) + .then((resp) => { + const r = resp.payload; + this.uiConf.sentence(sentence_a); + this.uiConf.rmToken(); + this.attCapsule.updateFromNormal(r, this.uiConf.hideClsSep()); + this.tokCapsule.updateFromResponse(r); + this._toggleTokenSel(); + this.update(); + clearInspector(); + this.sels.body.style("cursor", "default"); + }); + } + }; + const onEnter = ramda__WEBPACK_IMPORTED_MODULE_2__["curry"]((keyCode, f, event) => { + const e = event || window.event; + if (e.keyCode !== keyCode) + return; + e.preventDefault(); + f(); + }); + const onEnterSubmit = onEnter(13, submitNewSentence); + const btn = this.sels.form.button; + const inputBox = this.sels.form.sentenceA; + btn.on("click", submitNewSentence); + inputBox.on('keypress', onEnterSubmit); + } + _getSearchEmbeds() { + const savedToken = this.uiConf.token(); + const out = this.vizs.tokens[savedToken.side].getEmbedding(savedToken.ind); + return out.embeddings; + } + _getSearchContext() { + const savedToken = this.uiConf.token(); + const out = this.vizs.tokens[savedToken.side].getEmbedding(savedToken.ind); + return out.contexts; + } + _searchEmbeddings() { + const self = this; + console.log("SEARCHING EMBEDDINGS"); + const embed = this._getSearchEmbeds(); + const layer = self.uiConf.layer(); + const heads = self.uiConf.heads(); + const k = 50; + self.vizs.corpusInspector.showNext(self.uiConf.showNext); + this.sels.body.style("cursor", "progress"); + self.api.getNearestEmbeddings(self.uiConf.model(), self.uiConf.corpus(), embed, layer, heads, k) + .then((val) => { + if (val.status == 406) { + self.leaveCorpusMsg(`Embeddings are not available for model '${self.uiConf.model()}' and corpus '${self.uiConf.corpus()}' at this time.`); + } + else { + const v = val.payload; + self.vizs.corpusInspector.unhideView(); + self.vizs.corpusMatManager.unhideView(); + // Get heights of corpus inspector rows. + self.vizs.corpusInspector.update(v); + const wrappedVals = self._wrapResults(v); + const countedVals = wrappedVals.getMatchedHistogram(); + const offsetVals = wrappedVals.getMaxAttHistogram(); + self.vizs.corpusMatManager.update(wrappedVals.data); + self.sels.histograms.matchedWordDescription.text(this.uiConf.matchHistogramDescription); + console.log("MATCHER: ", self.sels.histograms.matchedWord); + self.vizs.histograms.matchedWord.update(countedVals); + self.vizs.histograms.maxAtt.update(offsetVals); + self.uiConf.displayInspector('embeddings'); + this._updateCorpusInspectorFromMeta(this.uiConf.metaMatch()); + } + this.sels.body.style("cursor", "default"); + }); + } + _searchContext() { + const self = this; + console.log("SEARCHING CONTEXTS"); + const context = this._getSearchContext(); + const layer = self.uiConf.layer(); + const heads = self.uiConf.heads(); + const k = 50; + self.vizs.corpusInspector.showNext(self.uiConf.showNext); + this.sels.body.style("cursor", "progress"); + self.api.getNearestContexts(self.uiConf.model(), self.uiConf.corpus(), context, layer, heads, k) + .then((val) => { + // Get heights of corpus inspector rows. + if (val.status == 406) { + console.log("Contexts are not available!"); + self.leaveCorpusMsg(`Contexts are not available for model '${self.uiConf.model()}' and corpus '${self.uiConf.corpus()}' at this time.`); + } + else { + const v = val.payload; + console.log("HIDING"); + self.vizs.corpusInspector.update(v); + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].hideElement(self.sels.corpusMsgBox); + self.vizs.corpusInspector.unhideView(); + self.vizs.corpusMatManager.unhideView(); + const wrappedVals = self._wrapResults(v); + const countedVals = wrappedVals.getMatchedHistogram(); + const offsetVals = wrappedVals.getMaxAttHistogram(); + self.vizs.corpusMatManager.update(wrappedVals.data); + self.vizs.histograms.matchedWord.update(countedVals); + self.vizs.histograms.maxAtt.update(offsetVals); + self.uiConf.displayInspector('context'); + this._updateCorpusInspectorFromMeta(this.uiConf.metaMatch()); + self.vizs.histograms.maxAtt.meta(self.uiConf.metaMax()); + } + this.sels.body.style("cursor", "default"); + }); + } + _queryContext() { + const self = this; + if (this.uiConf.hasToken()) { + this._searchContext(); + } + else { + console.log("Was told to show inspector but was not given a selected token embedding"); + } + } + _queryEmbeddings() { + const self = this; + if (this.uiConf.hasToken()) { + console.log("token: ", this.uiConf.token()); + this._searchEmbeddings(); + } + else { + console.log("Was told to show inspector but was not given a selected token embedding"); + } + } + _searchingDisabled() { + return (this.uiConf.heads().length == 0) || (!this.uiConf.hasToken()); + } + _searchDisabler() { + this._disableSearching(this._searchingDisabled()); + } + _initQueryForm() { + const self = this; + this._searchDisabler(); + this.sels.contextQuery.on("click", () => { + self._queryContext(); + }); + this.sels.embeddingQuery.on("click", () => { + self._queryEmbeddings(); + }); + } + _renderHeadSummary() { + this.sels.selectedHeads + .html(ramda__WEBPACK_IMPORTED_MODULE_2__["join"](', ', this.uiConf.heads().map(h => h + 1))); + } + // Modify faiss results with corresponding heights + _wrapResults(returnedFaissResults) { + const rows = d3__WEBPACK_IMPORTED_MODULE_0__["selectAll"]('.inspector-row'); + // Don't just use offsetHeight since that rounds to the nearest integer + const heights = rows.nodes().map((n) => n.getBoundingClientRect().height); + const newVals = returnedFaissResults.map((v, i) => { + return ramda__WEBPACK_IMPORTED_MODULE_2__["assoc"]('height', heights[i], v); + }); + const wrappedVals = new _data_FaissSearchWrapper__WEBPACK_IMPORTED_MODULE_16__["FaissSearchResultWrapper"](newVals, this.uiConf.showNext); + return wrappedVals; + } + initLayers(nLayers) { + const self = this; + let hasActive = false; + const checkboxes = self.sels.layerCheckboxes.selectAll(".layerCheckbox") + .data(lodash__WEBPACK_IMPORTED_MODULE_1__["range"](0, nLayers)) + .join("label") + .attr("class", "btn button layerCheckbox") + .classed('active', (d, i) => { + // Assign to largest layer available if uiConf.layer() > new nLayers + if (d == self.uiConf.layer()) { // Javascript is 0 indexed! + hasActive = true; + return true; + } + if (!hasActive && d == nLayers) { + self.uiConf.layer(d); + hasActive = true; + return true; + } + return false; + }) + .text((d) => d + 1) + .append("input") + .attr("type", "radio") + .attr("class", "checkbox-inline") + .attr("name", "layerbox") + // .attr("head", d => d) + .attr("id", (d, i) => "layerCheckbox" + i); + // .text((d, i) => d + " ") + Object(rxjs__WEBPACK_IMPORTED_MODULE_18__["fromEvent"])(checkboxes.nodes(), 'change').pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_19__["tap"])((e) => { + const myData = d3__WEBPACK_IMPORTED_MODULE_0__["select"](e.target).datum(); + console.log(myData, "--- myData"); + this.sels.layerCheckboxes.selectAll(".layerCheckbox") + .classed('active', d => d === myData); + }), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_19__["map"])((v) => +d3__WEBPACK_IMPORTED_MODULE_0__["select"](v.target).datum()), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_19__["tap"])(v => { + console.log("New layer: ", v); + self.uiConf.layer(v); + self.sels.body.style("cursor", "progress"); + }), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_19__["switchMap"])((v) => Object(rxjs__WEBPACK_IMPORTED_MODULE_18__["from"])(self.api.updateMaskedAttentions(self.uiConf.model(), self.tokCapsule.a, self.uiConf.sentence(), v)))).subscribe({ + next: (resp) => { + const r = resp.payload; + self.attCapsule.updateFromNormal(r, this.uiConf.hideClsSep()); + self.tokCapsule.updateTokens(r); + self.uiConf.maskInds(self.tokCapsule.a.maskInds); + self.update(); + self.sels.body.style("cursor", "default"); + self._toggleTokenSel(); + } + }); + const layerId = `#layerCheckbox${this.uiConf.layer()}`; + console.log("Layer ID: ", layerId); + d3__WEBPACK_IMPORTED_MODULE_0__["select"](layerId).attr("checked", "checked"); + // Init threshold stuff + const dispThresh = (thresh) => Math.round(thresh * 100); + d3__WEBPACK_IMPORTED_MODULE_0__["select"]('#my-range-value').text(dispThresh(self.uiConf.threshold())); + this.sels.threshSlider.on("input", lodash__WEBPACK_IMPORTED_MODULE_1__["throttle"](function () { + const node = this; + self.uiConf.threshold(+node.value / 100); + d3__WEBPACK_IMPORTED_MODULE_0__["select"]('#my-range-value').text(dispThresh(self.uiConf.threshold())); + self.vizs.attentionSvg.threshold(self.uiConf.threshold()); + }, 100)); + this.sels.headSelectAll.on("click", function () { + self.uiConf.selectAllHeads(); + self._searchDisabler(); + self.renderSvg(); + self.renderAttHead(); + }); + this.sels.headSelectNone.on("click", function () { + self.uiConf.selectNoHeads(); + self._searchDisabler(); + self.renderSvg(); + self.renderAttHead(); + _etc_Util__WEBPACK_IMPORTED_MODULE_17__["Sel"].setHidden(".atn-curve"); + }); + } + _initToggle() { + Object(rxjs__WEBPACK_IMPORTED_MODULE_18__["fromEvent"])(this.sels.clsToggle.node(), 'input').pipe( + // @ts-ignore -- TODO: FIX ! + Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_19__["map"])(e => e.srcElement.checked)).subscribe({ + next: v => { + this.uiConf.hideClsSep(v); + this.attCapsule.zeroed(v); + this.renderSvg(); + this.renderAttHead(); + } + }); + } + renderAttHead() { + const heads = lodash__WEBPACK_IMPORTED_MODULE_1__["range"](0, this.uiConf._nHeads); + const focusAtt = this.attCapsule.att; + const token = this.uiConf.hasToken() ? this.uiConf.token() : null; + //@ts-ignore + const leftAttInfo = Object(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["getAttentionInfo"])(focusAtt, heads, "left", token); + //@ts-ignore + const rightAttInfo = Object(_AttentionHeadBox__WEBPACK_IMPORTED_MODULE_8__["getAttentionInfo"])(focusAtt, heads, "right", token); + this.vizs.leftHeads.options.offset = this.uiConf.offset; + this.vizs.leftHeads.update(leftAttInfo); + this.vizs.rightHeads.update(rightAttInfo); + this._renderHeadSummary(); + // Make sure + heads.forEach((h) => { + if (this.uiConf.headSet().has(h)) { + selectHead(h); + } + else { + unselectHead(h); + } + }); + } + ; + renderTokens() { + const left = this.tokCapsule[this.uiConf.attType[0]]; + const right = this.tokCapsule[this.uiConf.attType[1]]; + console.log("now: ", this.uiConf.offset); + this.vizs.tokens.left.options.offset = this.uiConf.offset; + this.vizs.tokens.left.update(left.tokenData); + this.vizs.tokens.left.mask(left.maskInds); + this.vizs.tokens.right.update(right.tokenData); + this.vizs.tokens.right.mask(right.maskInds); + // displaySelectedToken + } + renderSvg() { + const att = this.attCapsule.byHeads(this.uiConf.heads()); + this.vizs.attentionSvg.options.offset = this.uiConf.offset; + const svg = this.vizs.attentionSvg.data(att); + svg.update(att); + const maxTokens = lodash__WEBPACK_IMPORTED_MODULE_1__["max"]([this.tokCapsule.a.length()]); + const newHeight = svg.options.boxheight * maxTokens; + svg.height(newHeight); + // Don't redisplay everything if one token is selected + showBySide(this.uiConf.token()); + } + ; + render() { + this.renderTokens(); + this.renderSvg(); + this.renderAttHead(); + } + update() { + this.render(); + } +} + + +/***/ }), + +/***/ 0: +/*!************************!*\ + !*** crypto (ignored) ***! + \************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), + +/***/ 1: +/*!****************************!*\ + !*** node-fetch (ignored) ***! + \****************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), + +/***/ 2: +/*!**********************!*\ + !*** util (ignored) ***! + \**********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), + +/***/ 3: +/*!************************!*\ + !*** crypto (ignored) ***! + \************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), + +/***/ 4: +/*!********************************!*\ + !*** string_decoder (ignored) ***! + \********************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }), + +/***/ 5: +/*!********************!*\ + !*** fs (ignored) ***! + \********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/* (ignored) */ + +/***/ }) + +/******/ }); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vLy4vY3NzL21haW4uc2NzcyIsIndlYnBhY2s6Ly8vLi9leEJFUlQuaHRtbCIsIndlYnBhY2s6Ly8vLi9pbmRleC5odG1sIiwid2VicGFjazovLy8uL3RzL2FwaS9kZW1vQVBJLnRzIiwid2VicGFjazovLy8uL3RzL2FwaS9tYWluQXBpLnRzIiwid2VicGFjazovLy8uL3RzL2RhdGEvQXR0ZW50aW9uQ2Fwc3VsZS50cyIsIndlYnBhY2s6Ly8vLi90cy9kYXRhL0ZhaXNzU2VhcmNoV3JhcHBlci50cyIsIndlYnBhY2s6Ly8vLi90cy9kYXRhL1Rva2VuV3JhcHBlci50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMvU1ZHcGx1cy50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMvU2ltcGxlRXZlbnRIYW5kbGVyLnRzIiwid2VicGFjazovLy8uL3RzL2V0Yy9TcGFjeUluZm8udHMiLCJ3ZWJwYWNrOi8vLy4vdHMvZXRjL1VSTEhhbmRsZXIudHMiLCJ3ZWJwYWNrOi8vLy4vdHMvZXRjL1V0aWwudHMiLCJ3ZWJwYWNrOi8vLy4vdHMvZXRjL19Ub29scy50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMvYXBpSGVscGVycy50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMvYXJyYXlVdGlscy50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMvY29sb3JzLnRzIiwid2VicGFjazovLy8uL3RzL2V0Yy90eXBlcy50cyIsIndlYnBhY2s6Ly8vLi90cy9ldGMveGQzLnRzIiwid2VicGFjazovLy8uL3RzL2V0Yy94cmFtZGEudHMiLCJ3ZWJwYWNrOi8vLy4vdHMvbWFpbi50cyIsIndlYnBhY2s6Ly8vLi90cy91aUNvbmZpZy50cyIsIndlYnBhY2s6Ly8vLi90cy92aXMvQXR0ZW50aW9uQ29ubmVjdG9yLnRzIiwid2VicGFjazovLy8uL3RzL3Zpcy9BdHRlbnRpb25IZWFkQm94LnRzIiwid2VicGFjazovLy8uL3RzL3Zpcy9Db3JwdXNIaXN0b2dyYW0udHMiLCJ3ZWJwYWNrOi8vLy4vdHMvdmlzL0NvcnB1c0luc3BlY3Rvci50cyIsIndlYnBhY2s6Ly8vLi90cy92aXMvQ29ycHVzTWF0TWFuYWdlci50cyIsIndlYnBhY2s6Ly8vLi90cy92aXMvRWRnZUNvbm5lY3Rvci50cyIsIndlYnBhY2s6Ly8vLi90cy92aXMvVGV4dFRva2VuLnRzIiwid2VicGFjazovLy8uL3RzL3Zpcy9WaXNDb21wb25lbnQudHMiLCJ3ZWJwYWNrOi8vLy4vdHMvdmlzL215TWFpbi50cyIsIndlYnBhY2s6Ly8vY3J5cHRvIChpZ25vcmVkKSIsIndlYnBhY2s6Ly8vbm9kZS1mZXRjaCAoaWdub3JlZCkiLCJ3ZWJwYWNrOi8vL3V0aWwgKGlnbm9yZWQpIiwid2VicGFjazovLy9jcnlwdG8gKGlnbm9yZWQpP2E4YjciLCJ3ZWJwYWNrOi8vL3N0cmluZ19kZWNvZGVyIChpZ25vcmVkKSIsIndlYnBhY2s6Ly8vZnMgKGlnbm9yZWQpIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7UUFBQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLFFBQVEsb0JBQW9CO1FBQzVCO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0EsaUJBQWlCLDRCQUE0QjtRQUM3QztRQUNBO1FBQ0Esa0JBQWtCLDJCQUEyQjtRQUM3QztRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7O1FBRUE7O1FBRUE7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTs7UUFFQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBOzs7UUFHQTtRQUNBOztRQUVBO1FBQ0E7O1FBRUE7UUFDQTtRQUNBO1FBQ0EsMENBQTBDLGdDQUFnQztRQUMxRTtRQUNBOztRQUVBO1FBQ0E7UUFDQTtRQUNBLHdEQUF3RCxrQkFBa0I7UUFDMUU7UUFDQSxpREFBaUQsY0FBYztRQUMvRDs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0EseUNBQXlDLGlDQUFpQztRQUMxRSxnSEFBZ0gsbUJBQW1CLEVBQUU7UUFDckk7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQSwyQkFBMkIsMEJBQTBCLEVBQUU7UUFDdkQsaUNBQWlDLGVBQWU7UUFDaEQ7UUFDQTtRQUNBOztRQUVBO1FBQ0Esc0RBQXNELCtEQUErRDs7UUFFckg7UUFDQTs7UUFFQTtRQUNBO1FBQ0E7UUFDQTtRQUNBLGdCQUFnQix1QkFBdUI7UUFDdkM7OztRQUdBO1FBQ0E7UUFDQTtRQUNBOzs7Ozs7Ozs7Ozs7QUN2SkEsdUM7Ozs7Ozs7Ozs7O0FDQUEsaUJBQWlCLHFCQUF1QixpQjs7Ozs7Ozs7Ozs7QUNBeEMsaUJBQWlCLHFCQUF1QixnQjs7Ozs7Ozs7Ozs7O0FDQXhDO0FBQUE7QUFBTyxNQUFNLE9BQU8sR0FBRztJQUN0QiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFFLCtDQUErQztJQUMzRiwwQ0FBMEMsRUFBRSwrQ0FBK0M7SUFDM0YsMENBQTBDLEVBQUUsK0NBQStDO0lBQzNGLDBDQUEwQyxFQUFF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QyxXQUFXLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQy9CO0lBRUQsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDOzs7Ozs7Ozs7Ozs7O0FDekNIO0FBQUE7QUFBQSw0SEFBNEg7QUFDckgsTUFBTSxTQUFTLEdBQUc7SUFDckIsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVM7SUFDdEYsU0FBUyxFQUFFLFNBQVMs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QSxDQUFDO0lBRUYsTUFBTTtRQUNGLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDakIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxNQUFNO1FBQ0YsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2xCLENBQUM7Q0FDSjs7Ozs7Ozs7Ozs7O0FDNy9CRCxlOzs7Ozs7Ozs7OztBQ0FBLGU7Ozs7Ozs7Ozs7O0FDQUEsZTs7Ozs7Ozs7Ozs7QUNBQSxlOzs7Ozs7Ozs7OztBQ0FBLGU7Ozs7Ozs7Ozs7O0FDQUEsZSIsImZpbGUiOiJtYWluLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gaW5zdGFsbCBhIEpTT05QIGNhbGxiYWNrIGZvciBjaHVuayBsb2FkaW5nXG4gXHRmdW5jdGlvbiB3ZWJwYWNrSnNvbnBDYWxsYmFjayhkYXRhKSB7XG4gXHRcdHZhciBjaHVua0lkcyA9IGRhdGFbMF07XG4gXHRcdHZhciBtb3JlTW9kdWxlcyA9IGRhdGFbMV07XG4gXHRcdHZhciBleGVjdXRlTW9kdWxlcyA9IGRhdGFbMl07XG5cbiBcdFx0Ly8gYWRkIFwibW9yZU1vZHVsZXNcIiB0byB0aGUgbW9kdWxlcyBvYmplY3QsXG4gXHRcdC8vIHRoZW4gZmxhZyBhbGwgXCJjaHVua0lkc1wiIGFzIGxvYWRlZCBhbmQgZmlyZSBjYWxsYmFja1xuIFx0XHR2YXIgbW9kdWxlSWQsIGNodW5rSWQsIGkgPSAwLCByZXNvbHZlcyA9IFtdO1xuIFx0XHRmb3IoO2kgPCBjaHVua0lkcy5sZW5ndGg7IGkrKykge1xuIFx0XHRcdGNodW5rSWQgPSBjaHVua0lkc1tpXTtcbiBcdFx0XHRpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaW5zdGFsbGVkQ2h1bmtzLCBjaHVua0lkKSAmJiBpbnN0YWxsZWRDaHVua3NbY2h1bmtJZF0pIHtcbiBcdFx0XHRcdHJlc29sdmVzLnB1c2goaW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdWzBdKTtcbiBcdFx0XHR9XG4gXHRcdFx0aW5zdGFsbGVkQ2h1bmtzW2NodW5rSWRdID0gMDtcbiBcdFx0fVxuIFx0XHRmb3IobW9kdWxlSWQgaW4gbW9yZU1vZHVsZXMpIHtcbiBcdFx0XHRpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9yZU1vZHVsZXMsIG1vZHVsZUlkKSkge1xuIFx0XHRcdFx0bW9kdWxlc1ttb2R1bGVJZF0gPSBtb3JlTW9kdWxlc1ttb2R1bGVJZF07XG4gXHRcdFx0fVxuIFx0XHR9XG4gXHRcdGlmKHBhcmVudEpzb25wRnVuY3Rpb24pIHBhcmVudEpzb25wRnVuY3Rpb24oZGF0YSk7XG5cbiBcdFx0d2hpbGUocmVzb2x2ZXMubGVuZ3RoKSB7XG4gXHRcdFx0cmVzb2x2ZXMuc2hpZnQoKSgpO1xuIFx0XHR9XG5cbiBcdFx0Ly8gYWRkIGVudHJ5IG1vZHVsZXMgZnJvbSBsb2FkZWQgY2h1bmsgdG8gZGVmZXJyZWQgbGlzdFxuIFx0XHRkZWZlcnJlZE1vZHVsZXMucHVzaC5hcHBseShkZWZlcnJlZE1vZHVsZXMsIGV4ZWN1dGVNb2R1bGVzIHx8IFtdKTtcblxuIFx0XHQvLyBydW4gZGVmZXJyZWQgbW9kdWxlcyB3aGVuIGFsbCBjaHVua3MgcmVhZHlcbiBcdFx0cmV0dXJuIGNoZWNrRGVmZXJyZWRNb2R1bGVzKCk7XG4gXHR9O1xuIFx0ZnVuY3Rpb24gY2hlY2tEZWZlcnJlZE1vZHVsZXMoKSB7XG4gXHRcdHZhciByZXN1bHQ7XG4gXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBkZWZlcnJlZE1vZHVsZXMubGVuZ3RoOyBpKyspIHtcbiBcdFx0XHR2YXIgZGVmZXJyZWRNb2R1bGUgPSBkZWZlcnJlZE1vZHVsZXNbaV07XG4gXHRcdFx0dmFyIGZ1bGZpbGxlZCA9IHRydWU7XG4gXHRcdFx0Zm9yKHZhciBqID0gMTsgaiA8IGRlZmVycmVkTW9kdWxlLmxlbmd0aDsgaisrKSB7XG4gXHRcdFx0XHR2YXIgZGVwSWQgPSBkZWZlcnJlZE1vZHVsZVtqXTtcbiBcdFx0XHRcdGlmKGluc3RhbGxlZENodW5rc1tkZXBJZF0gIT09IDApIGZ1bGZpbGxlZCA9IGZhbHNlO1xuIFx0XHRcdH1cbiBcdFx0XHRpZihmdWxmaWxsZWQpIHtcbiBcdFx0XHRcdGRlZmVycmVkTW9kdWxlcy5zcGxpY2UoaS0tLCAxKTtcbiBcdFx0XHRcdHJlc3VsdCA9IF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gZGVmZXJyZWRNb2R1bGVbMF0pO1xuIFx0XHRcdH1cbiBcdFx0fVxuXG4gXHRcdHJldHVybiByZXN1bHQ7XG4gXHR9XG5cbiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIG9iamVjdCB0byBzdG9yZSBsb2FkZWQgYW5kIGxvYWRpbmcgY2h1bmtzXG4gXHQvLyB1bmRlZmluZWQgPSBjaHVuayBub3QgbG9hZGVkLCBudWxsID0gY2h1bmsgcHJlbG9hZGVkL3ByZWZldGNoZWRcbiBcdC8vIFByb21pc2UgPSBjaHVuayBsb2FkaW5nLCAwID0gY2h1bmsgbG9hZGVkXG4gXHR2YXIgaW5zdGFsbGVkQ2h1bmtzID0ge1xuIFx0XHRcIm1haW5cIjogMFxuIFx0fTtcblxuIFx0dmFyIGRlZmVycmVkTW9kdWxlcyA9IFtdO1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG4gXHR2YXIganNvbnBBcnJheSA9IHdpbmRvd1tcIndlYnBhY2tKc29ucFwiXSA9IHdpbmRvd1tcIndlYnBhY2tKc29ucFwiXSB8fCBbXTtcbiBcdHZhciBvbGRKc29ucEZ1bmN0aW9uID0ganNvbnBBcnJheS5wdXNoLmJpbmQoanNvbnBBcnJheSk7XG4gXHRqc29ucEFycmF5LnB1c2ggPSB3ZWJwYWNrSnNvbnBDYWxsYmFjaztcbiBcdGpzb25wQXJyYXkgPSBqc29ucEFycmF5LnNsaWNlKCk7XG4gXHRmb3IodmFyIGkgPSAwOyBpIDwganNvbnBBcnJheS5sZW5ndGg7IGkrKykgd2VicGFja0pzb25wQ2FsbGJhY2soanNvbnBBcnJheVtpXSk7XG4gXHR2YXIgcGFyZW50SnNvbnBGdW5jdGlvbiA9IG9sZEpzb25wRnVuY3Rpb247XG5cblxuIFx0Ly8gYWRkIGVudHJ5IG1vZHVsZSB0byBkZWZlcnJlZCBsaXN0XG4gXHRkZWZlcnJlZE1vZHVsZXMucHVzaChbXCIuL3RzL21haW4udHNcIixcInZlbmRvclwiXSk7XG4gXHQvLyBydW4gZGVmZXJyZWQgbW9kdWxlcyB3aGVuIHJlYWR5XG4gXHRyZXR1cm4gY2hlY2tEZWZlcnJlZE1vZHVsZXMoKTtcbiIsIi8vIGV4dHJhY3RlZCBieSBtaW5pLWNzcy1leHRyYWN0LXBsdWdpbiIsIm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyBcImV4QkVSVC5odG1sXCI7IiwibW9kdWxlLmV4cG9ydHMgPSBfX3dlYnBhY2tfcHVibGljX3BhdGhfXyArIFwiaW5kZXguaHRtbFwiOyIsImV4cG9ydCBjb25zdCBEZW1vQVBJID0ge1xuXHRcIjUyN2ZkYWM0NDA0YmY5YmE1NDEyNjQ2YWQ0NTc5NTBkNDQ4Mjc2MmNcIjogXCI1MjdmZGFjNDQwNGJmOWJhNTQxMjY0NmFkNDU3OTUwZDQ0ODI3NjJjLmpzb25cIixcblx0XCI1OWI0YWNjMDVmMWQ4MGVjYmVmMWMyM2VhZjJmZGExMDIyMmNiMjU3XCI6IFwiNTliNGFjYzA1ZjFkODBlY2JlZjFjMjNlYWYyZmRhMTAyMjJjYjI1Ny5qc29uXCIsXG5cdFwiMzU0OTkyZjJlZTIzNjYwNGM4NzRhM2E2MjdlNDA0MmJjNjg1ODZmOFwiOiBcIjM1NDk5MmYyZWUyMzY2MDRjODc0YTNhNjI3ZTQwNDJiYzY4NTg2ZjguanNvblwiLFxuXHRcIjUwMTVlNWEzMTg2MDVjZWE2ODA4NTM4ZGIxNGQ4YWYxNjg4N2IwNzZcIjogXCI1MDE1ZTVhMzE4NjA1Y2VhNjgwODUzOGRiMTRkOGFmMTY4ODdiMDc2Lmpzb25cIixcblx0XCIzYzlhYTE1MmFjODk0MzA2MDQwNzAzYzUwOTU1OTliMTk5Y2FkMWE5XCI6IFwiM2M5YWExNTJhYzg5NDMwNjA0MDcwM2M1MDk1NTk5YjE5OWNhZDFhOS5qc29uXCIsXG5cdFwiMGZlY2UwYzg3MjAzZTgzYWZkMTY3NGI1YWVlYmFlZDBmNWZhMDU2MlwiOiBcIjBmZWNlMGM4NzIwM2U4M2FmZDE2NzRiNWFlZWJhZWQwZjVmYTA1NjIuanNvblwiLFxuXHRcImQzYTBlNDA0NWVhNDhhMjc1Y2U1MWE2YWYwMjgwNDA2MDYwZjQ3Y2ZcIjogXCJkM2EwZTQwNDVlYTQ4YTI3NWNlNTFhNmFmMDI4MDQwNjA2MGY0N2NmLmpzb25cIixcblx0XCJlZDk4ZDc1MWFiOWI2YTRhMGU4NWU5MzMyYjQyMGE0YzEzYWI3NWE3XCI6IFwiZWQ5OGQ3NTFhYjliNmE0YTBlODVlOTMzMmI0MjBhNGMxM2FiNzVhNy5qc29uXCIsXG5cdFwiMGQyNGFlMDhlZWIyMWFmODJjNjY2Y2JlMmFjMDY0NmVkOWM5ZDlhNlwiOiBcIjBkMjRhZTA4ZWViMjFhZjgyYzY2NmNiZTJhYzA2NDZlZDljOWQ5YTYuanNvblwiLFxuXHRcIjZkZTA1M2IzYjhhNGQ5MDQ3ODBjOWE2NTQ1YTBhNjNjYmJiMmIxNDRcIjogXCI2ZGUwNTNiM2I4YTRkOTA0NzgwYzlhNjU0NWEwYTYzY2JiYjJiMTQ0Lmpzb25cIixcblx0XCJmNjhkZjIzMzY1ZmFmMDJmOWMwMTQzOTM0NWJlZDY2OTM2ZWQ4NWY3XCI6IFwiZjY4ZGYyMzM2NWZhZjAyZjljMDE0MzkzNDViZWQ2NjkzNmVkODVmNy5qc29uXCIsXG5cdFwiNDYwOGNiNGZjMDBiNDNmZmY2ODA5OGU4NTY3NmZhZDU3Yzk0MGYwMlwiOiBcIjQ2MDhjYjRmYzAwYjQzZmZmNjgwOThlODU2NzZmYWQ1N2M5NDBmMDIuanNvblwiLFxuXHRcImRmY2Q1MDE0NmRhOGQ4MTIyYTVhNTdjMmEzYzBhYmNlNTAzYmE5NGJcIjogXCJkZmNkNTAxNDZkYThkODEyMmE1YTU3YzJhM2MwYWJjZTUwM2JhOTRiLmpzb25cIixcblx0XCIzNGM4NjI5ZDQyNjVkN2YzZWRlM2FkZDQyZjM2MTNiMjA1ZDk0YzFjXCI6IFwiMzRjODYyOWQ0MjY1ZDdmM2VkZTNhZGQ0MmYzNjEzYjIwNWQ5NGMxYy5qc29uXCIsXG5cdFwiZGIyZGMyNTJhNzg2NjUwZjY0Mzk1YTBmNWQxODFjMDgzMTAxOWNiZlwiOiBcImRiMmRjMjUyYTc4NjY1MGY2NDM5NWEwZjVkMTgxYzA4MzEwMTljYmYuanNvblwiLFxuXHRcImRhNDU5N2Q3M2Q0NDQ3NTdiZGU5MTc2Mzk1YmYzMWFhZDMzMzQxMzFcIjogXCJkYTQ1OTdkNzNkNDQ0NzU3YmRlOTE3NjM5NWJmMzFhYWQzMzM0MTMxLmpzb25cIixcblx0XCJhMmViZjEzZDNjOTM3MWZjZjczOGI5NjUxODI0ZTJjM2NkMWZmOGUwXCI6IFwiYTJlYmYxM2QzYzkzNzFmY2Y3MzhiOTY1MTgyNGUyYzNjZDFmZjhlMC5qc29uXCIsXG5cdFwiYmM0MTkyMzhjMjBkZDFjNWNmZTFjYzQyN2FiM2QxZTMxMzUzNDM2YVwiOiBcImJjNDE5MjM4YzIwZGQxYzVjZmUxY2M0MjdhYjNkMWUzMTM1MzQzNmEuanNvblwiLFxuXHRcIjg0ZThiZTlmZTU2MmZiZDA0ODdjMDNiNTVjYzZiNGYzZmI4Y2Q3ODdcIjogXCI4NGU4YmU5ZmU1NjJmYmQwNDg3YzAzYjU1Y2M2YjRmM2ZiOGNkNzg3Lmpzb25cIixcblx0XCIyMDdlNmM5OGEwZTE0OWRjN2U2ZWQ2NzExODI5NmQ4YThjODliM2MzXCI6IFwiMjA3ZTZjOThhMGUxNDlkYzdlNmVkNjcxMTgyOTZkOGE4Yzg5YjNjMy5qc29uXCIsXG5cdFwiYzE4NWE5MzQ5YmE1YTMyNWFjZjg1MTRlOWI1MGRlNzEyODA0ODhhYVwiOiBcImMxODVhOTM0OWJhNWEzMjVhY2Y4NTE0ZTliNTBkZTcxMjgwNDg4YWEuanNvblwiLFxuXHRcImRkZTQ4MWE1Y2QzNjY3YWU4YzZjNWI1ZTE0MjFkYzg4MmI2YTJkZDZcIjogXCJkZGU0ODFhNWNkMzY2N2FlOGM2YzViNWUxNDIxZGM4ODJiNmEyZGQ2Lmpzb25cIixcblx0XCJmNjNlMTRlOTM1ZDk4OTQ4YjRhMGViYzk2NjM0MDBkYmU0MjYzMzQ4XCI6IFwiZjYzZTE0ZTkzNWQ5ODk0OGI0YTBlYmM5NjYzNDAwZGJlNDI2MzM0OC5qc29uXCIsXG5cdFwiNzliOTY0ZDFhNWM4NTRkZWFlYWNlMjY4MTNmOTY5OTRiYjgyYWVmMlwiOiBcIjc5Yjk2NGQxYTVjODU0ZGVhZWFjZTI2ODEzZjk2OTk0YmI4MmFlZjIuanNvblwiLFxuXHRcIjNiMTE2OGVjOTZhZjAwYzRlODg3MzQxZTkyYTg3OGY4NzUyZTFkMTdcIjogXCIzYjExNjhlYzk2YWYwMGM0ZTg4NzM0MWU5MmE4NzhmODc1MmUxZDE3Lmpzb25cIixcblx0XCI4YzQ2MmJjMjk4ZTMxODNlZmE4ZDllODYzZTI1ZWE1ZDg5ODA2YjAzXCI6IFwiOGM0NjJiYzI5OGUzMTgzZWZhOGQ5ZTg2M2UyNWVhNWQ4OTgwNmIwMy5qc29uXCIsXG5cdFwiOTkzOTY5OGVkYWEyNWJiYWU5ZWUxZDI3ODY0ZTY5OGYxMzk2M2YwNlwiOiBcIjk5Mzk2OThlZGFhMjViYmFlOWVlMWQyNzg2NGU2OThmMTM5NjNmMDYuanNvblwiLFxuXHRcIjczZjFlZTQ5N2IzZTdiNjM5NGU1NTcyNmIxOGRiZjlkNTE0ZGNlYTZcIjogXCI3M2YxZWU0OTdiM2U3YjYzOTRlNTU3MjZiMThkYmY5ZDUxNGRjZWE2Lmpzb25cIixcblx0XCJjN2NkYjgwYmY4MTNlMWRlMjQxMjYwYWVkZTZjZDI4ZWE2NWNjZmFlXCI6IFwiYzdjZGI4MGJmODEzZTFkZTI0MTI2MGFlZGU2Y2QyOGVhNjVjY2ZhZS5qc29uXCIsXG5cdFwiYTk2ZmVkMTZlYWIxYmY2ZDA4ZTQwMDFjMDI4OTRkOWM1NDlkZjYyN1wiOiBcImE5NmZlZDE2ZWFiMWJmNmQwOGU0MDAxYzAyODk0ZDljNTQ5ZGY2MjcuanNvblwiLFxuXHRcImE4ZWFmMTBkYThkYzc1YjQyZTcyYmRjNzA5MTc3NjI0N2ZmZjk2NTdcIjogXCJhOGVhZjEwZGE4ZGM3NWI0MmU3MmJkYzcwOTE3NzYyNDdmZmY5NjU3Lmpzb25cIixcblx0XCJhODE5NGYyMzA5ZTFjNzFlOTc3ZWY4ZDNiZTU3MmFlMDBiMGU5MWYyXCI6IFwiYTgxOTRmMjMwOWUxYzcxZTk3N2VmOGQzYmU1NzJhZTAwYjBlOTFmMi5qc29uXCIsXG5cdFwiMmY0YTE1YjY2ZmNmYjBjN2E0M2EzM2Q5Mzc2Mzk5MDI4MmJmYzVhYVwiOiBcIjJmNGExNWI2NmZjZmIwYzdhNDNhMzNkOTM3NjM5OTAyODJiZmM1YWEuanNvblwiLFxuXHRcIjA2MDk1Y2VmNGE3ZjQ5YjE4ZjE1M2U2N2UzM2ZkZGI4MzFhMTViNDZcIjogXCIwNjA5NWNlZjRhN2Y0OWIxOGYxNTNlNjdlMzNmZGRiODMxYTE1YjQ2Lmpzb25cIixcblx0XCI0YzkzZWFmMGMwY2U1NmYxZTVkNTEwMDkxNmFiZjRkMzFlYjM1ZGE1XCI6IFwiNGM5M2VhZjBjMGNlNTZmMWU1ZDUxMDA5MTZhYmY0ZDMxZWIzNWRhNS5qc29uXCIsXG5cdFwiZjhjNDBjNjdjODUxYTA0ODlmNzQ4MGM5OWIzMWI0ZjYwNmMwMTg0YlwiOiBcImY4YzQwYzY3Yzg1MWEwNDg5Zjc0ODBjOTliMzFiNGY2MDZjMDE4NGIuanNvblwiLFxuXHRcImU0ZTcxZjZlYTU3YmUyZTA1ZDYyYWYwODI1YTgwZjE0NDQyMWUwMmRcIjogXCJlNGU3MWY2ZWE1N2JlMmUwNWQ2MmFmMDgyNWE4MGYxNDQ0MjFlMDJkLmpzb25cIixcblx0XCJlN2Q5ZDUyMDg4Mjc4MmM3Y2ZiZmZlYWRhYWYyMmI0YzBhMDgxYzdjXCI6IFwiZTdkOWQ1MjA4ODI3ODJjN2NmYmZmZWFkYWFmMjJiNGMwYTA4MWM3Yy5qc29uXCIsXG5cdFwiNGFhNGViMTBlYWQ0NGEwYTNjMmRkOTU0MDcwMTdhOTI4MTM4YjMyYlwiOiBcIjRhYTRlYjEwZWFkNDRhMGEzYzJkZDk1NDA3MDE3YTkyODEzOGIzMmIuanNvblwiLFxuXHRcImRhMzFkNTVlZThjYjAxYmNkYjI5NTcyY2I5MDJiOGU3OTk2ODViZTJcIjogXCJkYTMxZDU1ZWU4Y2IwMWJjZGIyOTU3MmNiOTAyYjhlNzk5Njg1YmUyLmpzb25cIixcblx0XCJlNDI3MTgxZmIwMmJiZjE5ZjdiYmI2NWM5ZDkzODlkMmQ5YTQxODEyXCI6IFwiZTQyNzE4MWZiMDJiYmYxOWY3YmJiNjVjOWQ5Mzg5ZDJkOWE0MTgxMi5qc29uXCIsXG5cdFwiYmJjYWI5ZTFjYTYwYTg1MWZkN2VjZmRhODBkZTQ3MGFmYTc0MDkzNlwiOiBcImJiY2FiOWUxY2E2MGE4NTFmZDdlY2ZkYTgwZGU0NzBhZmE3NDA5MzYuanNvblwiLFxuXHRcIjRkZTk2YWEyMDUwNzY4NjNjOWZiNGVhOTllMmJhODZmYTEzMWZmNzZcIjogXCI0ZGU5NmFhMjA1MDc2ODYzYzlmYjRlYTk5ZTJiYTg2ZmExMzFmZjc2Lmpzb25cIixcblx0XCJlNGM2ZDFiMzAwNGUzY2RkMGM4NzlhNTk2MzliNWNlOTkzMjA3YTk5XCI6IFwiZTRjNmQxYjMwMDRlM2NkZDBjODc5YTU5NjM5YjVjZTk5MzIwN2E5OS5qc29uXCIsXG5cdFwiZmJjOWRhNzliOGJmMzlkYzk5OTg0MDg1MjY3NDFmODExYTEzZTZhYVwiOiBcImZiYzlkYTc5YjhiZjM5ZGM5OTk4NDA4NTI2NzQxZjgxMWExM2U2YWEuanNvblwiLFxuXHRcIjUyODU1NGVlNGU2MTVjNjEyODdjNDBlZDlhMmFlYTY5YjkxYWY2YzlcIjogXCI1Mjg1NTRlZTRlNjE1YzYxMjg3YzQwZWQ5YTJhZWE2OWI5MWFmNmM5Lmpzb25cIixcblx0XCI1ZTcwNzNjMDNjMzdkMTk4MjZiMmZiNGE2NTk5Y2NhZWRkZTQ5MmU0XCI6IFwiNWU3MDczYzAzYzM3ZDE5ODI2YjJmYjRhNjU5OWNjYWVkZGU0OTJlNC5qc29uXCIsXG5cdFwiNzFjNGE4ODZjZGVlNThhMzcxYWUyMTE1MzExYjE1MGU4NGU1NTVmNlwiOiBcIjcxYzRhODg2Y2RlZTU4YTM3MWFlMjExNTMxMWIxNTBlODRlNTU1ZjYuanNvblwiLFxuXHRcIjRiY2UwOTcwYTQ2NWZlOWI5NjMwNWUwNmFmMTljNWQ5Yzk3ZDdjYzNcIjogXCI0YmNlMDk3MGE0NjVmZTliOTYzMDVlMDZhZjE5YzVkOWM5N2Q3Y2MzLmpzb25cIixcblx0XCJlZmRiMWYwYTcwZjIyZjgwZmYzY2VhMGNiNzliZWM3MTdmYzhiNmY3XCI6IFwiZWZkYjFmMGE3MGYyMmY4MGZmM2NlYTBjYjc5YmVjNzE3ZmM4YjZmNy5qc29uXCIsXG5cdFwiMTc0YzZmNzg2ZDEzOWNlMTExMzgxMDQ1ZDYwZDI1NjgyYTE2OGI5OVwiOiBcIjE3NGM2Zjc4NmQxMzljZTExMTM4MTA0NWQ2MGQyNTY4MmExNjhiOTkuanNvblwiLFxuXHRcImE4YzIzZTg4ZDZjYTZkNGVmZDI2NDZiMDc0MmMwZmEzMmRiZDU1YTRcIjogXCJhOGMyM2U4OGQ2Y2E2ZDRlZmQyNjQ2YjA3NDJjMGZhMzJkYmQ1NWE0Lmpzb25cIixcblx0XCJmNjk0OWMyODc1MmRlMzVhODcwZWZkZTMwODU4NWFjZDQ2YTI1Mjc4XCI6IFwiZjY5NDljMjg3NTJkZTM1YTg3MGVmZGUzMDg1ODVhY2Q0NmEyNTI3OC5qc29uXCIsXG5cdFwiYzFiZGI4Y2JhZmQ1ZDVkOGY2YmRhMmI0ZGIxNmI2YmMyZDYyZTE4YVwiOiBcImMxYmRiOGNiYWZkNWQ1ZDhmNmJkYTJiNGRiMTZiNmJjMmQ2MmUxOGEuanNvblwiLFxuXHRcIjJiODFhOGY2MDIyNTFjZjQwYjQ2ODJjOGNlZGIzOTY2YjkxMmQ3YzZcIjogXCIyYjgxYThmNjAyMjUxY2Y0MGI0NjgyYzhjZWRiMzk2NmI5MTJkN2M2Lmpzb25cIixcblx0XCI4Zjk0ZTg0M2QyNTEwMDQ3ZmQxYWY0NmYyNDlhZmU4N2ZmNDljYzJmXCI6IFwiOGY5NGU4NDNkMjUxMDA0N2ZkMWFmNDZmMjQ5YWZlODdmZjQ5Y2MyZi5qc29uXCIsXG5cdFwiNGUzZGRiNTE1NTBjMDNjNjRmZGJlNTU5MjUyNjY2NTEwMGQzMjkzMFwiOiBcIjRlM2RkYjUxNTUwYzAzYzY0ZmRiZTU1OTI1MjY2NjUxMDBkMzI5MzAuanNvblwiLFxuXHRcImY4MTZiMjNhZjlhYTQzMTJjODBlNjY4YTY2YTE1NmM5MzRjYjMzMGNcIjogXCJmODE2YjIzYWY5YWE0MzEyYzgwZTY2OGE2NmExNTZjOTM0Y2IzMzBjLmpzb25cIixcblx0XCIyZmUwNWE5MTFhNTc0YjhhNmQ0YjA1ZWIxM2RiOWUwOWFhYWNhZDJkXCI6IFwiMmZlMDVhOTExYTU3NGI4YTZkNGIwNWViMTNkYjllMDlhYWFjYWQyZC5qc29uXCIsXG5cdFwiNWM3MTQ5NjcyNjM5NWFhYTRkMGE2NTM3M2ZkMTY1MWI1YTBlNmIxZlwiOiBcIjVjNzE0OTY3MjYzOTVhYWE0ZDBhNjUzNzNmZDE2NTFiNWEwZTZiMWYuanNvblwiLFxufSIsImltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJztcbmltcG9ydCB7IGRlYnVnIH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgeyBUb2tlbkRpc3BsYXkgfSBmcm9tICcuLi9kYXRhL1Rva2VuV3JhcHBlcidcbmltcG9ydCAqIGFzIHRwIGZyb20gJy4uL2V0Yy90eXBlcydcbmltcG9ydCAqIGFzIHJzcCBmcm9tICcuL3Jlc3BvbnNlcydcbmltcG9ydCAqIGFzIFIgZnJvbSAncmFtZGEnXG5pbXBvcnQgeyBEZW1vQVBJIH0gZnJvbSAnLi9kZW1vQVBJJ1xuaW1wb3J0ICogYXMgaGFzaCBmcm9tICdvYmplY3QtaGFzaCdcbmltcG9ydCB7IG1ha2VVcmwsIHRvUGF5bG9hZCB9IGZyb20gJy4uL2V0Yy9hcGlIZWxwZXJzJ1xuaW1wb3J0IHsgVVJMSGFuZGxlciB9IGZyb20gJy4uL2V0Yy9VUkxIYW5kbGVyJztcblxuZXhwb3J0IGNvbnN0IGVtcHR5VG9rZW5EaXNwbGF5ID0gbmV3IFRva2VuRGlzcGxheSgpXG5cbmNvbnN0IGJhc2V1cmwgPSBVUkxIYW5kbGVyLmJhc2ljVVJMKClcblxuLyoqXG4gKiBBIHJld3JpdGUgb2YgYGQzLWZldGNoYCdzIGBkMy5qc29uYCBjYWxsYmFjay4gSWYgYW4gYXBpIGNhbGwgZmFpbHMsIG1ha2UgYSBiYWNrdXAgY2FsbCB0byBzcGVjaWZpZWQgdXJsIGFuZCBwYXlsb2FkLCBpZiBzcGVjaWZpZWQuXG4gKiBcbiAqIEBwYXJhbSByZXNwb25zZSBPYmplY3QgZXhwZWN0ZWQgYXQgdGltZSBvZiBjYWxsYmFja1xuICogQHBhcmFtIGJhY2t1cFVybCBCYWNrdXAgdXJsIGluIHRoZSBldmVudCBvZiBmYWlsXG4gKiBAcGFyYW0gYmFja3VwUGF5bG9hZCBCYWNrdXAgcGF5bG9hZCBpZiBtYWtpbmcgYSBwb3N0IHJlcXVlc3RcbiAqL1xuZnVuY3Rpb24gcmVzcG9uc2VKc29uKHJlc3BvbnNlLCBiYWNrdXBVcmwgPSBudWxsLCBiYWNrdXBQYXlsb2FkID0gbnVsbCkge1xuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgaWYgKGJhY2t1cFVybCAhPSBudWxsKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIlNUQVRJQyBGSUxFIE5PVCBGT1VORFwiKTtcbiAgICAgICAgICAgIHJldHVybiBmZXRjaChiYWNrdXBVcmwsIGJhY2t1cFBheWxvYWQpLnRoZW4ocmVzcG9uc2VKc29uKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVzcG9uc2Uuc3RhdHVzICsgXCIgXCIgKyByZXNwb25zZS5zdGF0dXNUZXh0KVxuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpXG59XG5cbi8qKlxuICogQ2hlY2sgZmlyc3QgaWYgdGhlIGluZm9ybWF0aW9uIGJlaW5nIHNlbnQgZXhpc3RzIGluIGEgc3RhdGljIGRlbW8gZmlsZS4gSWYgaXQgZG9lcywgc2VuZCB0aGF0LiBPdGhlcndpc2UsIG1ha2UgYSBub3JtYWwgY2FsbCB0byB0aGUgc2VydmVyLlxuICogXG4gKiBAcGFyYW0gdG9TZW5kIFRoZSBwYWNrZXQgb2YgaW5mb3JtYXRpb24gdG8gc2VuZCB0byBhbiBBUEkgZW5kcG9pbnRcbiAqIEBwYXJhbSBiYWNrdXBVcmwgQmFja3VwIHVybCBpbiB0aGUgZXZlbnQgdGhhdCB0aGUgZGVtbyBmaWxlIGlzIG5vdCBmb3VuZFxuICogQHBhcmFtIGJhY2t1cFBheWxvYWQgQmFja3VwIHBheWxvYWQgaWYgZGVtbyBmaWxlIG5vdCBmb3VuZCwgZm9yIFBPU1QgcmVxdWVzdHMgb25seVxuICovXG5mdW5jdGlvbiBjaGVja0RlbW9BUEkodG9TZW5kLCBiYWNrdXBVcmwgPSBudWxsLCBiYWNrdXBQYXlsb2FkID0gbnVsbCkge1xuICAgIGNvbnN0IGhzaCA9IGhhc2guc2hhMSh0b1NlbmQpO1xuICAgIGNvbnNvbGUubG9nKFwiQ0hFQ0tJTkcgREVNT0FQSTogXCIgKyBoc2gpO1xuICAgIGlmIChEZW1vQVBJLmhhc093blByb3BlcnR5KGhzaCkpIHtcbiAgICAgICAgLy8gUmVsaWVzIG9uIGEgc3ltYm9saWMgbGluayBiZWluZyBwcmVzZW50IGluIHRoZSBkaXN0IGZvbGRlciB0byB0aGUgZGVtbyBmb2xkZXJcbiAgICAgICAgY29uc3QgcGF0aCA9ICcuL2RlbW8vJyArIERlbW9BUElbaHNoXVxuICAgICAgICBjb25zb2xlLmxvZyhcIlRSWUlORyBUTyBTRU5ESU5HIFNUQVRJQzogXCIsIHBhdGgpO1xuICAgICAgICBjb25zdCBmb2xsb3cgPSAocmVzcG9uc2UpID0+IHJlc3BvbnNlSnNvbihyZXNwb25zZSwgYmFja3VwVXJsLCBiYWNrdXBQYXlsb2FkKVxuICAgICAgICByZXR1cm4gZmV0Y2gocGF0aCkudGhlbihmb2xsb3cpXG4gICAgfVxuICAgIHJldHVybiBkMy5qc29uKGJhY2t1cFVybCwgYmFja3VwUGF5bG9hZClcbn1cblxuXG5leHBvcnQgY2xhc3MgQVBJIHtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgYmFzZVVSTDogc3RyaW5nID0gbnVsbCkge1xuICAgICAgICBpZiAodGhpcy5iYXNlVVJMID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuYmFzZVVSTCA9IGJhc2V1cmwgKyAnL2FwaSc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRNb2RlbERldGFpbHMobW9kZWw6IHN0cmluZywgaGFzaE9iajoge30gfCBudWxsID0gbnVsbCk6IFByb21pc2U8cnNwLk1vZGVsRGV0YWlsUmVzcG9uc2U+IHtcbiAgICAgICAgY29uc3QgdG9TZW5kID0ge1xuICAgICAgICAgICAgbW9kZWw6IG1vZGVsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cmwgPSBtYWtlVXJsKHRoaXMuYmFzZVVSTCArIFwiL2dldC1tb2RlbC1kZXRhaWxzXCIsIHRvU2VuZClcbiAgICAgICAgY29uc29sZS5sb2coXCItLS0gR0VUIFwiICsgdXJsKTtcblxuICAgICAgICBpZiAoaGFzaE9iaiAhPSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBoYXNoLnNoYTEodG9TZW5kKVxuICAgICAgICAgICAgZDMuanNvbih1cmwpLnRoZW4ociA9PiB7XG4gICAgICAgICAgICAgICAgaGFzaE9ialtrZXldID0gcjtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hlY2tEZW1vQVBJKHRvU2VuZCwgdXJsKVxuICAgIH1cblxuICAgIGdldE1ldGFBdHRlbnRpb25zKG1vZGVsOiBzdHJpbmcsIHNlbnRlbmNlOiBzdHJpbmcsIGxheWVyOiBudW1iZXIsIGhhc2hPYmo6IHt9IHwgbnVsbCA9IG51bGwpOiBQcm9taXNlPHJzcC5BdHRlbnRpb25EZXRhaWxzUmVzcG9uc2U+IHtcbiAgICAgICAgY29uc3QgdG9TZW5kID0ge1xuICAgICAgICAgICAgbW9kZWw6IG1vZGVsLFxuICAgICAgICAgICAgc2VudGVuY2U6IHNlbnRlbmNlLFxuICAgICAgICAgICAgbGF5ZXI6IGxheWVyXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdXJsID0gbWFrZVVybCh0aGlzLmJhc2VVUkwgKyBcIi9hdHRlbmQrbWV0YVwiLCB0b1NlbmQpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiLS0tIEdFVCBcIiArIHVybCk7XG5cbiAgICAgICAgLy8gQWRkIGhhc2ggYW5kIHZhbHVlIHRvIGhhc2hPYmpcbiAgICAgICAgaWYgKGhhc2hPYmogIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gaGFzaC5zaGExKHRvU2VuZClcbiAgICAgICAgICAgIGQzLmpzb24odXJsKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGhhc2hPYmpba2V5XSA9IHI7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNoZWNrRGVtb0FQSSh0b1NlbmQsIHVybClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGRpc3BsYXkgYmFzZWQgb24gdGhlIGluZm9ybWF0aW9uIHRoYXQgd2FzIGFscmVhZHkgcGFyc2VkIGZyb20gdGhlIHBhc3NlZCBzZW50ZW5jZS5cbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gYSBUaGUgZGlzcGxheWVkIHRva2VucyBpbiB0aGUgY29sdW1ucyBcbiAgICAgKiBAcGFyYW0gc2VudGVuY2VBIFRoZSBvcmlnaW5hbCBzZW50ZW5jZSB0aGF0IGxlZCB0byB0aGUgdG9rZW5pemVkIGluZm9ybWF0aW9uIGluIGBhYFxuICAgICAqIEBwYXJhbSBsYXllciBXaGljaCBsYXllciB0byBzZWFyY2ggYXRcbiAgICAgKiBAcGFyYW0gaGFzaE9iaiBJZiBub3QgbnVsbCwgc3RvcmUgdGhlIGluZm9ybWF0aW9uIG9mIHRoZSByZXNwb25zZXMgaW50byB0aGUgcGFzc2VkIG9iamVjdC4gVXNlZCBmb3IgY3JlYXRpbmcgZGVtb3MuXG4gICAgICovXG4gICAgdXBkYXRlTWFza2VkQXR0ZW50aW9ucyhtb2RlbDogc3RyaW5nLCB0b2tlbnM6IFRva2VuRGlzcGxheSwgc2VudGVuY2U6IHN0cmluZywgbGF5ZXI6IG51bWJlciwgaGFzaE9iajoge30gfCBudWxsID0gbnVsbCk6IFByb21pc2U8cnNwLkF0dGVudGlvbkRldGFpbHNSZXNwb25zZT4ge1xuICAgICAgICBjb25zdCB0b1NlbmQgPSB7XG4gICAgICAgICAgICBtb2RlbDogbW9kZWwsXG4gICAgICAgICAgICB0b2tlbnM6IFIubWFwKFIucHJvcCgndGV4dCcpLCB0b2tlbnMudG9rZW5EYXRhKSxcbiAgICAgICAgICAgIHNlbnRlbmNlOiBzZW50ZW5jZSxcblxuICAgICAgICAgICAgLy8gRW1wdHkgbWFza3MgbmVlZCB0byBiZSBzZW50IGFzIGEgbnVtYmVyLCB1bmZvcnR1bmF0ZWx5LiBDaG9vc2luZyAtMSBmb3IgdGhpc1xuICAgICAgICAgICAgbWFzazogdG9rZW5zLm1hc2tJbmRzLmxlbmd0aCA/IHRva2Vucy5tYXNrSW5kcyA6IFstMV0sXG4gICAgICAgICAgICBsYXllcjogbGF5ZXIsXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cmwgPSBtYWtlVXJsKHRoaXMuYmFzZVVSTCArICcvdXBkYXRlLW1hc2snKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IHRvUGF5bG9hZCh0b1NlbmQpXG5cblxuICAgICAgICBpZiAoaGFzaE9iaiAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyBBZGQgaGFzaCBhbmQgdmFsdWUgdG8gaGFzaE9iaiBmb3IgZGVtbyBwdXJwb3Nlc1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gaGFzaC5zaGExKHRvU2VuZClcbiAgICAgICAgICAgIGQzLmpzb24odXJsLCBwYXlsb2FkKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGhhc2hPYmpba2V5XSA9IHI7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc29sZS5sb2coXCItLS0gUE9TVCBcIiArIHVybCwgcGF5bG9hZCk7XG5cbiAgICAgICAgcmV0dXJuIGNoZWNrRGVtb0FQSSh0b1NlbmQsIHVybCwgcGF5bG9hZClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gZW1iZWRkaW5nIEVtYmVkZGluZyBvZiB0aGUgd29yZFxuICAgICAqIEBwYXJhbSBsYXllciBJbiB0aGUgbCd0aCBsYXllclxuICAgICAqIEBwYXJhbSBrIGhvdyBtYW55IHJlc3VsdHMgdG8gcmV0cmlldmVcbiAgICAgKi9cbiAgICBnZXROZWFyZXN0RW1iZWRkaW5ncyhtb2RlbDogc3RyaW5nLCBjb3JwdXM6IHN0cmluZywgZW1iZWRkaW5nOiBudW1iZXJbXSwgbGF5ZXI6IG51bWJlciwgaGVhZHM6IG51bWJlcltdLCBrID0gMTAsIGhhc2hPYmo6IHt9IHwgbnVsbCA9IG51bGwpOiBQcm9taXNlPHJzcC5OZWFyZXN0TmVpZ2hib3JSZXNwb25zZT4ge1xuICAgICAgICBjb25zdCB0b1NlbmQgPSB7XG4gICAgICAgICAgICBtb2RlbDogbW9kZWwsXG4gICAgICAgICAgICBjb3JwdXM6IGNvcnB1cyxcbiAgICAgICAgICAgIGVtYmVkZGluZzogZW1iZWRkaW5nLFxuICAgICAgICAgICAgbGF5ZXI6IGxheWVyLFxuICAgICAgICAgICAgaGVhZHM6IGhlYWRzLFxuICAgICAgICAgICAgazogayxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHVybCA9IG1ha2VVcmwodGhpcy5iYXNlVVJMICsgJy9rLW5lYXJlc3QtZW1iZWRkaW5ncycsIHRvU2VuZCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiLS0tIEdFVCBcIiArIHVybCk7XG5cbiAgICAgICAgaWYgKGhhc2hPYmogIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gaGFzaC5zaGExKHRvU2VuZClcbiAgICAgICAgICAgIGQzLmpzb24odXJsKS50aGVuKHIgPT4ge1xuICAgICAgICAgICAgICAgIGhhc2hPYmpba2V5XSA9IHI7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNoZWNrRGVtb0FQSSh0b1NlbmQsIHVybClcbiAgICB9XG5cbiAgICBnZXROZWFyZXN0Q29udGV4dHMobW9kZWw6IHN0cmluZywgY29ycHVzOiBzdHJpbmcsIGNvbnRleHQ6IG51bWJlcltdLCBsYXllcjogbnVtYmVyLCBoZWFkczogbnVtYmVyW10sIGsgPSAxMCwgaGFzaE9iajoge30gfCBudWxsID0gbnVsbCk6IFByb21pc2U8cnNwLk5lYXJlc3ROZWlnaGJvclJlc3BvbnNlPiB7XG4gICAgICAgIGNvbnN0IHRvU2VuZCA9IHtcbiAgICAgICAgICAgIG1vZGVsOiBtb2RlbCxcbiAgICAgICAgICAgIGNvcnB1czogY29ycHVzLFxuICAgICAgICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgICAgICAgIGxheWVyOiBsYXllcixcbiAgICAgICAgICAgIGhlYWRzOiBoZWFkcyxcbiAgICAgICAgICAgIGs6IGssXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cmwgPSBtYWtlVXJsKHRoaXMuYmFzZVVSTCArICcvay1uZWFyZXN0LWNvbnRleHRzJywgdG9TZW5kKTtcbiAgICAgICAgY29uc29sZS5sb2coXCItLS0gR0VUIFwiICsgdXJsKTtcblxuICAgICAgICBpZiAoaGFzaE9iaiAhPSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBoYXNoLnNoYTEodG9TZW5kKVxuICAgICAgICAgICAgZDMuanNvbih1cmwpLnRoZW4ociA9PiB7XG4gICAgICAgICAgICAgICAgaGFzaE9ialtrZXldID0gcjtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2hlY2tEZW1vQVBJKHRvU2VuZCwgdXJsKVxuICAgIH1cbn07XG4iLCJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCdcbmltcG9ydCAqIGFzIHhfIGZyb20gJy4uL2V0Yy9fVG9vbHMnXG5pbXBvcnQgKiBhcyB0cCBmcm9tICcuLi9ldGMvdHlwZXMnXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICdAdGVuc29yZmxvdy90ZmpzJ1xuXG4vKipcbiAqIE5vdGVzOlxuICogXG4gKiAtIEFsc28gZW5jYXBzdWxhdGUgdGhlIENMUy9TRVAgaW5mbyB2cy4gbm8gQ0xTL1NFUCBpbmZvXG4gKiAtIFdoZW4gbGF5ZXIgZm9ybWF0IGNoYW5nZXMgZnJvbSBsaXN0LCBkcm9wIHRoZSBpbmRleCBpbnRvIGNvbmYubGF5ZXJcbiAqL1xuXG5jb25zdCBicGVUb2tlbnMgPSBbXCJbQ0xTXVwiLCBcIltTRVBdXCIsIFwiPHM+XCIsIFwiPC9zPlwiLCBcIjx8ZW5kb2Z0ZXh0fD5cIl1cbmNvbnN0IGZpbmRCYWRJbmRleGVzID0gKHg6IHRwLkZ1bGxTaW5nbGVUb2tlbkluZm9bXSkgPT4geF8uZmluZEFsbEluZGV4ZXMoeC5tYXAodCA9PiB0LnRleHQpLCAoYSkgPT4gXy5pbmNsdWRlcyhicGVUb2tlbnMsIGEpKVxuXG5leHBvcnQgZnVuY3Rpb24gbWFrZUZyb21NZXRhUmVzcG9uc2Uocjp0cC5BdHRlbnRpb25SZXNwb25zZSwgaXNaZXJvZWQpe1xuICAgIGNvbnN0IGtleSA9ICdhYScgLy8gQ2hhbmdlIHRoaXMgaWYgYmFja2VuZCByZXNwb25zZSBjaGFuZ2VzIHRvIGJlIHNpbXBsZXJcbiAgICBjb25zdCBjdXJyUGFpciA9IHJba2V5XVxuICAgIGNvbnN0IGxlZnQgPSA8dHAuRnVsbFNpbmdsZVRva2VuSW5mb1tdPmN1cnJQYWlyLmxlZnRcbiAgICBjb25zdCByaWdodCA9IDx0cC5GdWxsU2luZ2xlVG9rZW5JbmZvW10+Y3VyclBhaXIucmlnaHRcbiAgICBjb25zdCBsZWZ0WmVybyA9IHhfLmZpbmRBbGxJbmRleGVzKGxlZnQubWFwKHQgPT4gdC50ZXh0KSwgKGEpID0+IF8uaW5jbHVkZXMoYnBlVG9rZW5zLCBhKSlcbiAgICBjb25zdCByaWdodFplcm8gPSB4Xy5maW5kQWxsSW5kZXhlcyhyaWdodC5tYXAodCA9PiB0LnRleHQpLCAoYSkgPT4gXy5pbmNsdWRlcyhicGVUb2tlbnMsIGEpKVxuICAgIHJldHVybiBuZXcgQXR0ZW50aW9uV3JhcHBlcihjdXJyUGFpci5hdHQsIFtsZWZ0WmVybywgcmlnaHRaZXJvXSwgaXNaZXJvZWQpXG59XG5cbmV4cG9ydCBjbGFzcyBBdHRlbnRpb25XcmFwcGVyIHtcbiAgICBwcm90ZWN0ZWQgX2F0dDpudW1iZXJbXVtdW11cbiAgICBwcm90ZWN0ZWQgX2F0dFRlbnNvcjp0Zi5UZW5zb3IzRFxuICAgIHByb3RlY3RlZCBfemVyb2VkQXR0VGVuc29yOnRmLlRlbnNvcjNEXG5cbiAgICBiYWRUb2tzOltudW1iZXJbXSwgbnVtYmVyW11dIC8vIEluZGV4ZXMgZm9yIHRoZSBDTFMgYW5kIFNFUCB0b2tlbnNcbiAgICBpc1plcm9lZDogYm9vbGVhblxuICAgIG5MYXllcnMgPSAxMjtcbiAgICBuSGVhZHMgPSAxMjtcblxuICAgIGNvbnN0cnVjdG9yKGF0dDpudW1iZXJbXVtdW10sIGJhZFRva3M6W251bWJlcltdLCBudW1iZXJbXV09W1tdLFtdXSwgaXNaZXJvZWQ9dHJ1ZSl7XG4gICAgICAgIHRoaXMuaW5pdChhdHQsIGJhZFRva3MsIGlzWmVyb2VkKVxuICAgIH1cblxuICAgIGluaXQoYXR0Om51bWJlcltdW11bXSwgYmFkVG9rczpbbnVtYmVyW10sIG51bWJlcltdXT1bW10sW11dLCBpc1plcm9lZCkge1xuICAgICAgICB0aGlzLmlzWmVyb2VkID0gaXNaZXJvZWRcbiAgICAgICAgdGhpcy5fYXR0ID0gYXR0O1xuICAgICAgICB0aGlzLl96ZXJvZWRBdHRUZW5zb3IgPSB6ZXJvUm93Q29sKHRmLnRlbnNvcjNkKGF0dCksIGJhZFRva3NbMF0sIGJhZFRva3NbMV0pXG4gICAgICAgIHRoaXMuX2F0dFRlbnNvciA9IHRmLnRlbnNvcjNkKGF0dCkgLy8gSWYgSSBwdXQgdGhpcyBmaXJzdCwgYnVmZmVyIG1vZGlmaWNhdGlvbnMgY2hhbmdlIHRoaXMgdG9vLlxuICAgICAgICB0aGlzLmJhZFRva3MgPSBiYWRUb2tzO1xuICAgIH1cblxuICAgIHVwZGF0ZUZyb21Ob3JtYWwocjp0cC5BdHRlbnRpb25SZXNwb25zZSwgaXNaZXJvZWQpe1xuICAgICAgICBjb25zdCBrZXkgPSAnYWEnIC8vIENoYW5nZSB0aGlzIGlmIGJhY2tlbmQgcmVzcG9uc2UgY2hhbmdlcyB0byBiZSBzaW1wbGVyXG4gICAgICAgIGNvbnN0IGN1cnJQYWlyID0gcltrZXldXG4gICAgICAgIGNvbnN0IGxlZnQgPSA8dHAuRnVsbFNpbmdsZVRva2VuSW5mb1tdPmN1cnJQYWlyLmxlZnRcbiAgICAgICAgY29uc3QgcmlnaHQgPSA8dHAuRnVsbFNpbmdsZVRva2VuSW5mb1tdPmN1cnJQYWlyLnJpZ2h0XG5cbiAgICAgICAgY29uc3QgbGVmdFplcm8gPSBmaW5kQmFkSW5kZXhlcyhsZWZ0KVxuICAgICAgICBjb25zdCByaWdodFplcm8gPSBmaW5kQmFkSW5kZXhlcyhyaWdodClcbiAgICAgICAgdGhpcy5pbml0KGN1cnJQYWlyLmF0dCwgW2xlZnRaZXJvLCByaWdodFplcm9dLCBpc1plcm9lZClcbiAgICB9XG5cbiAgICBnZXQgYXR0VGVuc29yKCkge1xuICAgICAgICBjb25zdCB0ZW5zID0gdGhpcy5pc1plcm9lZCA/IHRoaXMuX3plcm9lZEF0dFRlbnNvciA6IHRoaXMuX2F0dFRlbnNvclxuICAgICAgICByZXR1cm4gdGVuc1xuICAgIH1cblxuICAgIGdldCBhdHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dFRlbnNvci5hcnJheVN5bmMoKVxuICAgIH1cblxuICAgIHplcm9lZCgpOiBib29sZWFuXG4gICAgemVyb2VkKHZhbDpib29sZWFuKTogdGhpc1xuICAgIHplcm9lZCh2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkgcmV0dXJuIHRoaXMuaXNaZXJvZWRcbiAgICAgICAgdGhpcy5pc1plcm9lZCA9IHZhbFxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHRvZ2dsZVplcm9pbmcoKSB7XG4gICAgICAgIHRoaXMuemVyb2VkKCF0aGlzLnplcm9lZCgpKVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBfYnlIZWFkcyhoZWFkczpudW1iZXJbXSk6dGYuVGVuc29yMkQge1xuICAgICAgICBpZiAoaGVhZHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0Zi56ZXJvc0xpa2UodGhpcy5fYnlIZWFkKDApKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICg8dGYuVGVuc29yMkQ+dGhpcy5hdHRUZW5zb3IuZ2F0aGVyKGhlYWRzLCAwKS5zdW0oMCkpXG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIF9ieUhlYWQoaGVhZDpudW1iZXIpOnRmLlRlbnNvcjJEIHtcbiAgICAgICAgcmV0dXJuICg8dGYuVGVuc29yMkQ+dGhpcy5hdHRUZW5zb3IuZ2F0aGVyKFtoZWFkXSwgMCkuc3F1ZWV6ZShbMF0pKVxuICAgIH1cblxuICAgIGJ5SGVhZHMoaGVhZHM6bnVtYmVyW10pOm51bWJlcltdW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnlIZWFkcyhoZWFkcykuYXJyYXlTeW5jKClcbiAgICB9XG5cbiAgICBieUhlYWQoaGVhZDpudW1iZXIpOm51bWJlcltdW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnlIZWFkKGhlYWQpLmFycmF5U3luYygpXG4gICAgfVxufVxuXG5mdW5jdGlvbiB6ZXJvUm93Q29sKHRlbnM6dGYuVGVuc29yM0QsIHJvd3M6bnVtYmVyW10sIGNvbHM6bnVtYmVyW10pOnRmLlRlbnNvcjNEIHtcbiAgICBsZXQgb3V0VGVucyA9IHRlbnMuY2xvbmUoKVxuICAgIGxldCBhdGIgPSBvdXRUZW5zLmJ1ZmZlclN5bmMoKVxuICAgIF8ucmFuZ2UoYXRiLnNoYXBlWzBdKS5mb3JFYWNoKChoZWFkKSA9PiB7XG4gICAgICAgIF8ucmFuZ2UoYXRiLnNoYXBlWzFdKS5mb3JFYWNoKChpKSA9PiB7XG4gICAgICAgICAgICAvLyBTZXQgcm93cyB0byAwXG4gICAgICAgICAgICBpZiAoXy5pbmNsdWRlcyhyb3dzLCBpKSkge1xuICAgICAgICAgICAgICAgIF8ucmFuZ2UoYXRiLnNoYXBlWzJdKS5mb3JFYWNoKChqKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGF0Yi5zZXQoMCwgaGVhZCwgaSwgailcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTZXQgY29scyB0byAwXG4gICAgICAgICAgICBfLnJhbmdlKGF0Yi5zaGFwZVsyXSkuZm9yRWFjaCgoaikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChfLmluY2x1ZGVzKGNvbHMsIGopKVxuICAgICAgICAgICAgICAgICAgICBfLnJhbmdlKGF0Yi5zaGFwZVsxXSkuZm9yRWFjaCgoaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXRiLnNldCgwLCBoZWFkLCBpLCBqKVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIG91dFRlbnNcbn0iLCJpbXBvcnQgKiBhcyB0cCBmcm9tICcuLi9ldGMvdHlwZXMnXG5pbXBvcnQgKiBhcyBkMyBmcm9tICdkMydcbmltcG9ydCAnZDMtYXJyYXknXG5pbXBvcnQgKiBhcyBSIGZyb20gJ3JhbWRhJ1xuaW1wb3J0IHtTcGFjeUluZm99IGZyb20gJy4uL2V0Yy9TcGFjeUluZm8nXG5pbXBvcnQge2luaXRaZXJvfSBmcm9tICcuLi9ldGMveHJhbWRhJ1xuXG4vLyBJZiB2YWx1ZSBpcyBub3QgYSBzdHJpbmcsIGRvbid0IHRyeSB0byBtYWtlIGxvd2VyY2FzZVxuY29uc3QgbWFrZVN0cmluZ0xvd2VyID0gUi5pZkVsc2UoUi5pcyhTdHJpbmcpLCBSLnRvTG93ZXIsIFIuaWRlbnRpdHkpXG5cbmZ1bmN0aW9uIGFyZ01heChhcnJheTpudW1iZXJbXSkge1xuICByZXR1cm4gW10ubWFwLmNhbGwoYXJyYXksICh4LCBpKSA9PiBbeCwgaV0pLnJlZHVjZSgociwgYSkgPT4gKGFbMF0gPiByWzBdID8gYSA6IHIpKVsxXTtcbn1cblxuXG5leHBvcnQgY2xhc3MgRmFpc3NTZWFyY2hSZXN1bHRXcmFwcGVyIHtcbiAgICBkYXRhOiB0cC5GYWlzc1NlYXJjaFJlc3VsdHNbXVxuXG4gICAgb3B0aW9ucyA9IHtcbiAgICAgICAgc2hvd05leHQ6IGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoZGF0YTogdHAuRmFpc3NTZWFyY2hSZXN1bHRzW10sIHNob3dOZXh0PWZhbHNlKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGFcbiAgICAgICAgdGhpcy5vcHRpb25zLnNob3dOZXh0ID0gc2hvd05leHRcbiAgICB9XG5cbiAgICBnZXQgbWF0Y2hBdHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNob3dOZXh0KCkgPyBcIm1hdGNoZWRfYXR0X3BsdXNfMVwiIDogXCJtYXRjaGVkX2F0dFwiXG4gICAgfVxuXG4gICAgZ2V0IG1hdGNoSWR4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zaG93TmV4dCgpID8gXCJuZXh0X2luZGV4XCIgOiBcImluZGV4XCJcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGQgcG9zaXRpb24gaW5mbyBpbnRlcnByZXRhYmxlIGJ5IHRoZSBoaXN0b2dyYW1cbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gY291bnRPYmogUmVwcmVzZW50cyB0aGUgaW5mb3JybWF0aW9uIHRvIGJlIGRpc3BsYXllZCBieSB0aGUgaGlzdG9ncmFtXG4gICAgICovXG4gICAgY291bnRQb3NJbmZvKCkge1xuICAgICAgICBjb25zdCBhdHRPZmZzZXRzID0gdGhpcy5kYXRhLm1hcCgoZCxpKSA9PiArZFt0aGlzLm1hdGNoQXR0XS5vdXQub2Zmc2V0X3RvX21heClcblxuICAgICAgICBjb25zdCBjdE9iaiA9IHtcbiAgICAgICAgICAgIG9mZnNldDogaW5pdFplcm8oYXR0T2Zmc2V0cylcbiAgICAgICAgfVxuXG4gICAgICAgIGF0dE9mZnNldHMuZm9yRWFjaCh2ID0+IHtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGN0T2JqKS5mb3JFYWNoKChrKSA9PiB7XG4gICAgICAgICAgICAgICAgY3RPYmpba11bdl0gKz0gMVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gY3RPYmpcbiAgICB9XG5cbiAgICBjb3VudE1heEF0dEtleXMoaW5kZXhPZmZzZXQ9MCkge1xuICAgICAgICAvLyBUaGUga2V5cyBpbiB0aGUgYmVsb3cgb2JqZWN0IGRpY3RhdGUgd2hhdCB3ZSBjb3VudFxuICAgICAgICBjb25zdCBjb3VudE9iaiA9IHtcbiAgICAgICAgICAgIHBvczogaW5pdFplcm8oU3BhY3lJbmZvLlRvdGFsTWV0YU9wdGlvbnMucG9zKSxcbiAgICAgICAgICAgIGRlcDogaW5pdFplcm8oU3BhY3lJbmZvLlRvdGFsTWV0YU9wdGlvbnMuZGVwKSxcbiAgICAgICAgICAgIGlzX2VudDogaW5pdFplcm8oU3BhY3lJbmZvLlRvdGFsTWV0YU9wdGlvbnMuaXNfZW50KSxcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbmZ1c2luZzogU2hvdyBNQVRDSEVEIFdPUkQgYXR0ZW50aW9ucywgYnV0IE5FWFQgV09SRCBkaXN0cmlidXRpb25cbiAgICAgICAgY29uc3QgZ2V0TWF4VG9rZW4gPSAoZDogdHAuRmFpc3NTZWFyY2hSZXN1bHRzKSA9PiBkLnRva2Vuc1thcmdNYXgoZC5tYXRjaGVkX2F0dC5vdXQuYXR0KV1cblxuICAgICAgICB0aGlzLmRhdGEuZm9yRWFjaCgoZCwgaSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWF4TWF0Y2ggPSBnZXRNYXhUb2tlbihkKVxuXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhjb3VudE9iaikuZm9yRWFjaChrID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSBtYWtlU3RyaW5nTG93ZXIoU3RyaW5nKG1heE1hdGNoW2tdKSlcbiAgICAgICAgICAgICAgICBjb3VudE9ialtrXVt2YWxdICs9IDE7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IG5ld0NvdW50T2JqID0gT2JqZWN0LmFzc2lnbihjb3VudE9iaiwgdGhpcy5jb3VudFBvc0luZm8oKSlcbiAgICAgICAgcmV0dXJuIG5ld0NvdW50T2JqXG4gICAgfVxuXG4gICAgY291bnRNYXRjaGVkS2V5cyhpbmRleE9mZnNldD0wKSB7XG4gICAgICAgIC8vIFRoZSBrZXlzIGluIHRoZSBiZWxvdyBvYmplY3QgZGljdGF0ZSB3aGF0IHdlIGNvdW50XG4gICAgICAgIGNvbnN0IGNvdW50T2JqID0ge1xuICAgICAgICAgICAgcG9zOiBpbml0WmVybyhTcGFjeUluZm8uVG90YWxNZXRhT3B0aW9ucy5wb3MpLFxuICAgICAgICAgICAgZGVwOiBpbml0WmVybyhTcGFjeUluZm8uVG90YWxNZXRhT3B0aW9ucy5kZXApLFxuICAgICAgICAgICAgaXNfZW50OiBpbml0WmVybyhTcGFjeUluZm8uVG90YWxNZXRhT3B0aW9ucy5pc19lbnQpLFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5kYXRhLmZvckVhY2goZCA9PiB7XG4gICAgICAgIC8vIENvbmZ1c2luZzogU2hvdyBNQVRDSEVEIFdPUkQgYXR0ZW50aW9ucywgYnV0IE5FWFQgV09SRCBkaXN0cmlidXRpb25cbiAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gZC50b2tlbnNbZFt0aGlzLm1hdGNoSWR4XSArIGluZGV4T2Zmc2V0XVxuXG4gICAgICAgICAgICBPYmplY3Qua2V5cyhjb3VudE9iaikuZm9yRWFjaChrID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWwgPSBtYWtlU3RyaW5nTG93ZXIoU3RyaW5nKG1hdGNoW2tdKSlcbiAgICAgICAgICAgICAgICBjb3VudE9ialtrXVt2YWxdICs9IDE7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgICAgIHJldHVybiBjb3VudE9ialxuICAgIH1cblxuICAgIGdldE1hdGNoZWRIaXN0b2dyYW0oaW5kZXhPZmZzZXQ9MCkge1xuICAgICAgICBjb25zdCB0b3RhbEhpc3QgPSB0aGlzLmNvdW50TWF0Y2hlZEtleXMoaW5kZXhPZmZzZXQpXG4gICAgICAgIGNvbnN0IGZpbHRlclplcm9zID0gKHZhbCwga2V5KSA9PiB2YWwgIT0gMDtcbiAgICAgICAgY29uc3Qgbm9uWmVybyA9IFIubWFwKFIucGlja0J5KGZpbHRlclplcm9zKSwgdG90YWxIaXN0KVxuXG4gICAgICAgIHJldHVybiBub25aZXJvXG4gICAgfVxuXG4gICAgZ2V0TWF4QXR0SGlzdG9ncmFtKCkge1xuICAgICAgICAvLyBjb25zdCB0b3RhbEhpc3QgPSB0aGlzLmNvdW50UG9zSW5mbygpXG4gICAgICAgIGNvbnN0IG5ld0hpc3QgPSB0aGlzLmNvdW50TWF4QXR0S2V5cygpXG4gICAgICAgIGNvbnN0IGZpbHRlclplcm9zID0gKHZhbCwga2V5KSA9PiB2YWwgIT0gMDtcbiAgICAgICAgY29uc3Qgbm9uWmVybyA9IFIubWFwKFIucGlja0J5KGZpbHRlclplcm9zKSwgbmV3SGlzdClcblxuICAgICAgICByZXR1cm4gbm9uWmVyb1xuICAgIH1cblxuICAgIHNob3dOZXh0KCk6IGJvb2xlYW5cbiAgICBzaG93TmV4dCh2OmJvb2xlYW4pOiB0aGlzXG4gICAgc2hvd05leHQodj8pIHtcbiAgICAgICAgaWYgKHYgPT0gbnVsbCkgcmV0dXJuIHRoaXMub3B0aW9ucy5zaG93TmV4dFxuXG4gICAgICAgIHRoaXMub3B0aW9ucy5zaG93TmV4dCA9IHZcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG59IiwiaW1wb3J0ICogYXMgeF8gZnJvbSAnLi4vZXRjL19Ub29scydcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJ1xuaW1wb3J0ICogYXMgdHAgZnJvbSAnLi4vZXRjL3R5cGVzJ1xuaW1wb3J0ICogYXMgUiBmcm9tICdyYW1kYSdcblxuLyoqXG4gKiBUaGUgb3JpZ2luYWwgdG9rZW5zLCBhbmQgdGhlIGluZGV4ZXMgdGhhdCBuZWVkIHRvIGJlIG1hc2tlZFxuICovXG4gY29uc3QgZW1wdHlGdWxsUmVzcG9uc2U6IHRwLkZ1bGxTaW5nbGVUb2tlbkluZm9bXSA9IFt7XG4gICAgIHRleHQ6ICdbU0VQXScsXG4gICAgIGVtYmVkZGluZ3M6IFtdLFxuICAgICBjb250ZXh0czogW10sXG4gICAgIGJwZV90b2tlbjogJycsXG4gICAgIGJwZV9wb3M6ICcnLFxuICAgICBicGVfZGVwOiAnJyxcbiAgICAgYnBlX2lzX2VudDogbnVsbCxcbiAgICAgdG9wa193b3JkczogW10sXG4gICAgIHRvcGtfcHJvYnM6IFtdXG4gfV1cblxuZXhwb3J0IGNsYXNzIFRva2VuRGlzcGxheSAge1xuICAgIHRva2VuRGF0YTp0cC5GdWxsU2luZ2xlVG9rZW5JbmZvW11cbiAgICBtYXNrSW5kczpudW1iZXJbXVxuXG4gICAgY29uc3RydWN0b3IodG9rZW5zPWVtcHR5RnVsbFJlc3BvbnNlLCBtYXNrSW5kcz1bXSl7XG4gICAgICAgIHRoaXMudG9rZW5EYXRhID0gdG9rZW5zO1xuICAgICAgICB0aGlzLm1hc2tJbmRzID0gbWFza0luZHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHVzaCBpZHggdG8gdGhlIG1hc2sgaWR4IGxpc3QgaW4gb3JkZXIgZnJvbSBzbWFsbGVzdCB0byBsYXJnZXN0XG4gICAgICovXG4gICAgbWFzayh2YWwpIHtcbiAgICAgICAgY29uc3QgY3VyckluZCA9IF8uaW5kZXhPZih0aGlzLm1hc2tJbmRzLCB2YWwpXG4gICAgICAgIGlmIChjdXJySW5kID09IC0xKSB7XG4gICAgICAgICAgICB4Xy5vcmRlcmVkSW5zZXJ0Xyh0aGlzLm1hc2tJbmRzLCB2YWwpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHt2YWx9IGFscmVhZHkgaW4gbWFza0luZHMhYCk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLm1hc2tJbmRzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRvZ2dsZSh2YWwpIHtcbiAgICAgICAgY29uc3QgY3VyckluZCA9IF8uaW5kZXhPZih0aGlzLm1hc2tJbmRzLCB2YWwpXG4gICAgICAgIGlmIChjdXJySW5kID09IC0xKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgTWFza2luZyAke3ZhbH1gKTtcbiAgICAgICAgICAgIHRoaXMubWFzayh2YWwpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgVW5tYXNraW5nICR7dmFsfWApO1xuICAgICAgICAgICAgdGhpcy51bm1hc2sodmFsKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdW5tYXNrKHZhbCkge1xuICAgICAgICBfLnB1bGwodGhpcy5tYXNrSW5kcywgdmFsKTtcbiAgICB9XG5cbiAgICByZXNldE1hc2soKSB7XG4gICAgICAgIHRoaXMubWFza0luZHMgPSBbXTtcbiAgICB9XG5cbiAgICBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRva2VuRGF0YS5sZW5ndGg7XG4gICAgfVxuXG4gICAgY29uY2F0KG90aGVyOiBUb2tlbkRpc3BsYXkpIHtcbiAgICAgICAgY29uc3QgbmV3VG9rZW5zID0gXy5jb25jYXQodGhpcy50b2tlbkRhdGEsIG90aGVyLnRva2VuRGF0YSk7XG4gICAgICAgIGNvbnN0IG5ld01hc2sgPSBfLmNvbmNhdCh0aGlzLm1hc2tJbmRzLCBvdGhlci5tYXNrSW5kcy5tYXAoeCA9PiB4ICsgdGhpcy5sZW5ndGgoKSkpO1xuICAgICAgICByZXR1cm4gbmV3IFRva2VuRGlzcGxheShuZXdUb2tlbnMsIG5ld01hc2spO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRva2VuV3JhcHBlciB7XG4gICAgYTogVG9rZW5EaXNwbGF5XG5cbiAgICBjb25zdHJ1Y3RvcihyOnRwLkF0dGVudGlvblJlc3BvbnNlKXtcbiAgICAgICAgdGhpcy51cGRhdGVGcm9tUmVzcG9uc2Uocik7XG4gICAgfVxuXG4gICAgdXBkYXRlRnJvbVJlc3BvbnNlKHI6dHAuQXR0ZW50aW9uUmVzcG9uc2UpIHtcbiAgICAgICAgY29uc3QgdG9rZW5zQSA9IHIuYWEubGVmdDtcbiAgICAgICAgdGhpcy51cGRhdGVGcm9tQ29tcG9uZW50cyh0b2tlbnNBLCBbXSlcbiAgICB9XG5cbiAgICB1cGRhdGVGcm9tQ29tcG9uZW50cyhhOnRwLkZ1bGxTaW5nbGVUb2tlbkluZm9bXSwgbWFza0E6bnVtYmVyW10pe1xuICAgICAgICB0aGlzLmEgPSBuZXcgVG9rZW5EaXNwbGF5KGEsIG1hc2tBKVxuICAgIH1cblxuICAgIHVwZGF0ZVRva2VucyhyOiB0cC5BdHRlbnRpb25SZXNwb25zZSkge1xuICAgICAgICBjb25zdCBkZXNpcmVkS2V5cyA9IFsnY29udGV4dHMnLCAnZW1iZWRkaW5ncycsICd0b3BrX3Byb2JzJywgJ3RvcGtfd29yZHMnXVxuICAgICAgICBjb25zdCBuZXdUb2tlbnMgPSByLmFhLmxlZnQubWFwKHYgPT4gUi5waWNrKGRlc2lyZWRLZXlzLCB2KSlcblxuICAgICAgICBjb25zdCBwYWlycyA9IFIuemlwKHRoaXMuYS50b2tlbkRhdGEsIG5ld1Rva2VucylcblxuICAgICAgICBwYWlycy5mb3JFYWNoKChkLCBpKSA9PiB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhkWzFdKS5tYXAoayA9PiB7XG4gICAgICAgICAgICAgICAgZFswXVtrXSA9IGRbMV1ba11cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pXG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYXNrIHRoZSBhcHByb3ByaWF0ZSBzZW50ZW5jZSBhdCB0aGUgaW5kZXggaW5kaWNhdGVkXG4gICAgICovXG4gICAgbWFzayhzSUQ6dHAuVG9rZW5PcHRpb25zLCBpZHg6bnVtYmVyKXtcbiAgICAgICAgdGhpc1tzSURdLm1hc2soaWR4KVxuICAgICAgICBjb25zdCBvcHRzID0gW1wiYVwiLCBcImJcIl1cbiAgICAgICAgY29uc3QgTmEgPSB0aGlzLmEubGVuZ3RoKCk7XG4gICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2lkZVRvTGV0dGVyKHNpZGU6dHAuU2lkZU9wdGlvbnMsIGF0eXBlOnRwLlNlbnRlbmNlT3B0aW9ucyl7XG4gICAgLy8gY29uc3QgYXR5cGUgPSBjb25mLmF0dFR5cGU7XG4gICAgaWYgKGF0eXBlID09IFwiYWxsXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiYWxsXCJcbiAgICB9XG4gICAgY29uc3Qgb3V0ID0gc2lkZSA9PSBcImxlZnRcIiA/IGF0eXBlWzBdIDogYXR5cGVbMV0gLy8gTm8gdHlwZSBjaGVja2luZz9cbiAgICByZXR1cm4gb3V0XG59XG4iLCJpbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIlxuaW1wb3J0ICdkMy1zZWxlY3Rpb24tbXVsdGknXG5pbXBvcnQgeyBEM1NlbCB9IGZyb20gJy4uL2V0Yy9VdGlsJ1xuXG4vKipcbiAqIENyZWF0ZWQgYnkgaGVuIG9uIDUvMTUvMTcuXG4gKiBNb2RpZmllZCBieSBob28gb24gNC8xNi8xOS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNWRyB7XG4gICAgc3RhdGljIHRyYW5zbGF0ZSh7eCwgeX0pOnN0cmluZyB7XG4gICAgICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArIHggKyBcIixcIiArIHkgKyBcIilcIlxuICAgIH1cblxuICAgIHN0YXRpYyByb3RhdGUoZGVnKTpzdHJpbmcge1xuICAgICAgICByZXR1cm4gYHJvdGF0ZSgke2RlZ30pYFxuICAgIH1cblxuICAgIHN0YXRpYyBncm91cChwYXJlbnQsIGNsYXNzZXMsIHBvcyA9IHt4OiAwLCB5OiAwfSkge1xuICAgICAgICByZXR1cm4gcGFyZW50LmFwcGVuZCgnZycpLmF0dHJzKHtcbiAgICAgICAgICAgIGNsYXNzOiBjbGFzc2VzLFxuICAgICAgICAgICAgXCJ0cmFuc2Zvcm1cIjogU1ZHLnRyYW5zbGF0ZShwb3MpXG4gICAgICAgIH0pXG4gICAgfVxuXG59XG5cbmV4cG9ydCBjbGFzcyBTVkdNZWFzdXJlbWVudHMge1xuXG4gICAgcHJpdmF0ZSBtZWFzdXJlRWxlbWVudDogZDMuU2VsZWN0aW9uPGFueSwgYW55LCBhbnksIGFueT47XG5cbiAgICBjb25zdHJ1Y3RvcihiYXNlRWxlbWVudCwgY2xhc3NlcyA9ICcnKSB7XG4gICAgICAgIHRoaXMubWVhc3VyZUVsZW1lbnQgPSBiYXNlRWxlbWVudC5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAgICAgLmF0dHJzKHt4OiAwLCB5OiAtMjAsIGNsYXNzOiBjbGFzc2VzfSlcblxuICAgIH1cblxuICAgIHRleHRMZW5ndGgodGV4dCwgc3R5bGUgPSBudWxsKSB7XG4gICAgICAgIHRoaXMubWVhc3VyZUVsZW1lbnQuYXR0cignc3R5bGUnLCBzdHlsZSk7XG4gICAgICAgIHRoaXMubWVhc3VyZUVsZW1lbnQudGV4dCh0ZXh0KTtcbiAgICAgICAgY29uc3QgdGwgPSAoPFNWR1RleHRFbGVtZW50PiB0aGlzLm1lYXN1cmVFbGVtZW50Lm5vZGUoKSkuZ2V0Q29tcHV0ZWRUZXh0TGVuZ3RoKCk7XG4gICAgICAgIHRoaXMubWVhc3VyZUVsZW1lbnQudGV4dCgnJyk7XG5cbiAgICAgICAgcmV0dXJuIHRsO1xuICAgIH1cbn0iLCIvKipcbiAqIENyZWF0ZWQgYnkgaGVuIG9uIDUvMTUvMTcuXG4gKiBNb2RpZmllZCBieSBob28gb24gNC8xNi8xOS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNpbXBsZUV2ZW50SGFuZGxlciB7XG5cbiAgICBlbGVtZW50OiBFbGVtZW50O1xuICAgIGV2ZW50TGlzdGVuZXJzOiBvYmplY3RbXTtcblxuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnQ6IEVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy5lbGVtZW50ID0gZWxlbWVudDtcbiAgICAgICAgdGhpcy5ldmVudExpc3RlbmVycyA9IFtdXG4gICAgfVxuXG4gICAgYmluZChldmVudE5hbWVzOiBzdHJpbmcsIGV2ZW50RnVuY3Rpb246IEZ1bmN0aW9uKSB7XG4gICAgICAgIGZvciAoY29uc3QgZXZlbnROYW1lIG9mIGV2ZW50TmFtZXMuc3BsaXQoJyAnKSkge1xuICAgICAgICAgICAgdGhpcy5ldmVudExpc3RlbmVycy5wdXNoKHtldmVudE5hbWUsIGV2ZW50RnVuY3Rpb259KTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50RnVuY3Rpb25XcmFwID0gZSA9PiBldmVudEZ1bmN0aW9uKGUuZGV0YWlsLCBlKTtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgZXZlbnRGdW5jdGlvbldyYXAsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldExpc3RlbmVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgdHJpZ2dlcihldmVudE5hbWU6IHN0cmluZywgZGV0YWlsOiBvYmplY3QpIHtcbiAgICAgICAgdGhpcy5lbGVtZW50LmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KGV2ZW50TmFtZSwge2RldGFpbH0pKTtcbiAgICB9XG59IiwiaW1wb3J0ICogYXMgdHAgZnJvbSAnLi90eXBlcydcbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJ1xuaW1wb3J0ICogYXMgUiBmcm9tICdyYW1kYSdcbmltcG9ydCB7Q09MT1JTMjAwfSBmcm9tICcuLi9ldGMvY29sb3JzJyBcblxuZXhwb3J0IGNsYXNzIFNwYWN5SW5mbyB7XG4gICAgY29sb3JTY2FsZTp0cC5Db2xvck1ldGFTY2FsZVxuXG4gICAgY29uc3RydWN0b3IoKXtcbiAgICAgICAgdGhpcy5jb2xvclNjYWxlID0gdGhpcy5jcmVhdGVDb2xvclNjYWxlcygpO1xuICAgIH1cblxuICAgIHN0YXRpYyBFbmdsaXNoTWV0YU9wdGlvbnM6IHRwLk1ldGFPcHRpb25zID0ge1xuICAgICAgICBwb3M6IFsncHVuY3QnLCAnc3ltJywgJ3gnLCAnYWRqJywgJ3ZlcmInLCAnY29uaicsICdudW0nLCAnZXQnLCAnYWR2JywgJ3gnLCAnYWRwJywgJ25vdW4nLCAncHJvcG4nLCAncGFydCcsICdwcm9uJywgJ3NwYWNlJywgJ2ludGonXSxcbiAgICAgICAgZGVwOiBbJ3Jvb3QnLCAnUk9PVCcsICdhY2wnLCAnYWNvbXAnLCAnYWR2Y2wnLCAnYWR2bW9kJywgJ2FnZW50JywgJ2Ftb2QnLCAnYXBwb3MnLCAnYXR0cicsICdhdXgnLCAnYXV4cGFzcycsICdjYXNlJywgJ2NjJywgJ2Njb21wJywgJ2NvbXBvdW5kJywgJ2NvbmonLCAnY29wJywgJ2NzdWJqJywgXG4gICAgICAgICdjc3VianBhc3MnLCAnZGF0aXZlJywgJ2RlcCcsICdkZXQnLCAnZG9iaicsICdleHBsJywgJ2ludGonLCAnbWFyaycsICdtZXRhJywgJ25lZycsICdubicsICdub3VubW9kJywgJ25wbW9kJywgJ25zdWJqJywgJ25zdWJqcGFzcycsICdudW1tb2QnLCAnb3ByZCcsIFxuICAgICAgICAnb2JqJywgJ29ibCcsICdwYXJhdGF4aXMnLCAncGNvbXAnLCAncG9iaicsICdwb3NzJywgJ3ByZWNvbmonLCAncHJlZGV0JywgJ3ByZXAnLCAncHJ0JywgJ3B1bmN0JywgJ3F1YW50bW9kJywgJ3JlbGNsJywgJ3Jvb3QnLCAneGNvbXAnLCAnbnBhZHZtb2QnXSxcbiAgICAgICAgaXNfZW50OiBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICBlbnRzOiBbJ3BlcnNvbicsICdub3JwJywgJ2ZhYycsICdvcmcnLCAnZ3BlJywgJ2xvYycsICdwcm9kdWN0JywgJ2V2ZW50JywgJ3dvcmtfb2ZfYXJ0JywgJ2xhdycsICdsYW5ndWFnZScsICdkYXRlJywgJ3RpbWUnLCAncGVyY2VudCcsICdtb25leScsICdxdWFudGl0eScsICdvcmRpbmFsJywgXG4gICAgICAgICAgICAgICAgJ2NhcmRpbmFsJ10sXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT2Jzb2xldGUuIFJlcHJlc2VudHMgdGhlIGluZm9ybWF0aW9uIHRoYXQgaXMgaW5jbHVkZWQgd2hlbiB0cmFpbmVkIG9uIHRoZSB1bml2ZXJzYWwgY29ycHVzXG4gICAgICovXG4gICAgc3RhdGljIFVuaXZlcnNhbE1ldGFPcHRpb25zOiB0cC5NZXRhT3B0aW9ucyA9IHtcbiAgICAgICAgcG9zOiBbJ2FkaicsICdhZHAnLCAnYWR2JywgJ2F1eCcsICdjb25qJywgJ2Njb25qJywgJ2RldCcsICdpbnRqJywgJ25vdW4nLCAnbnVtJywgJ3BhcnQnLCAncHJvbicsICdwcm9wbicsICdwdW5jdCcsICdzY29uaicsICdzeW0nLCAndmVyYicsICd4JywgJ3NwYWNlJ10sXG4gICAgICAgIGRlcDogWydhY2wnLCAnYWR2Y2wnLCAnYWR2bW9kJywgJ2Ftb2QnLCAnYXBwb3MnLCAnYXV4JywgJ2Nhc2UnLCAnY2MnLCAnY2NvbXAnLCAnY2xmJywgJ2NvbXBvdW5kJywgJ2NvbmonLCAnY29wJywgJ2NzdWJqJywgJ2RlcCcsICdkZXQnLCAnZGlzY291cnNlJywgXG4gICAgICAgICAgICAgICAgJ2Rpc2xvY2F0ZWQnLCAnZXhwbCcsICdmaXhlZCcsICdmbGF0JywgJ2dvZXN3aXRoJywgJ2lvYmonLCAnbGlzdCcsICdtYXJrJywgJ25tb2QnLCAnbnN1YmonLCAnbnVtbW9kJywgJ29iaicsICdvYmwnLCAnb3JwaGFuJywgJ3BhcmF0YXhpcycsICdwdW5jdCcsICdyZXBhcmFuZHVtJywgXG4gICAgICAgICAgICAgICAgJ3Jvb3QnLCAndm9jYXRpdmUnLCAneGNvbXAnXSxcbiAgICAgICAgaXNfZW50OiBbdHJ1ZSwgZmFsc2VdLFxuICAgICAgICBlbnRzOiBbJ3BlcnNvbicsICdub3JwJywgJ2ZhYycsICdvcmcnLCAnZ3BlJywgJ2xvYycsICdwcm9kdWN0JywgJ2V2ZW50JywgJ3dvcmtfb2ZfYXJ0JywgJ2xhdycsICdsYW5ndWFnZScsICdkYXRlJywgJ3RpbWUnLCAncGVyY2VudCcsICdtb25leScsICdxdWFudGl0eScsICdvcmRpbmFsJywgXG4gICAgICAgICAgICAgICAgJ2NhcmRpbmFsJ10sXG4gICAgfVxuXG4gICAgc3RhdGljIFRvdGFsTWV0YU9wdGlvbnM6IHRwLk1ldGFPcHRpb25zID0ge1xuICAgICAgICBwb3M6IFIudW5pb24oU3BhY3lJbmZvLkVuZ2xpc2hNZXRhT3B0aW9ucy5wb3MsIFNwYWN5SW5mby5Vbml2ZXJzYWxNZXRhT3B0aW9ucy5wb3MpLFxuICAgICAgICBkZXA6IFNwYWN5SW5mby5FbmdsaXNoTWV0YU9wdGlvbnMuZGVwLFxuICAgICAgICBpc19lbnQ6IFNwYWN5SW5mby5FbmdsaXNoTWV0YU9wdGlvbnMuaXNfZW50LFxuICAgICAgICBlbnRzOiBTcGFjeUluZm8uRW5nbGlzaE1ldGFPcHRpb25zLmVudHMsXG4gICAgfVxuXG4gICAgY3JlYXRlQ29sb3JTY2FsZXMoKTogdHAuQ29sb3JNZXRhU2NhbGV7XG4gICAgICAgIGNvbnN0IHRvU2NhbGUgPSAoa2V5czogQXJyYXk8bnVtYmVyfHN0cmluZ3xib29sZWFuPikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb2JqID0gUi56aXBPYmooUi5tYXAoU3RyaW5nLCBrZXlzKSwgQ09MT1JTMjAwLnNsaWNlKDAsIGtleXMubGVuZ3RoKSlcbiAgICAgICAgICAgIHJldHVybiBrID0+IFIucHJvcE9yKFwiYmxhY2tcIiwgaywgb2JqKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbXlDb2xvcnMgPSB7XG4gICAgICAgICAgICBwb3M6IHRvU2NhbGUoU3BhY3lJbmZvLlRvdGFsTWV0YU9wdGlvbnMucG9zKSxcbiAgICAgICAgICAgIGRlcDogdG9TY2FsZShTcGFjeUluZm8uVG90YWxNZXRhT3B0aW9ucy5kZXApLFxuICAgICAgICAgICAgaXNfZW50OiB0b1NjYWxlKFNwYWN5SW5mby5Ub3RhbE1ldGFPcHRpb25zLmlzX2VudCksXG4gICAgICAgICAgICBlbnRzOiB0b1NjYWxlKFNwYWN5SW5mby5Ub3RhbE1ldGFPcHRpb25zLmVudHMpLFxuICAgICAgICAgICAgb2Zmc2V0OiBkMy5zY2FsZU9yZGluYWwoKS5yYW5nZShbJ2JsYWNrJ10pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gPHRwLkNvbG9yTWV0YVNjYWxlPjx1bmtub3duPm15Q29sb3JzXG4gICAgfVxufVxuXG5leHBvcnQgY29uc3Qgc3BhY3lDb2xvcnMgPSBuZXcgU3BhY3lJbmZvKCk7IiwiLyoqXG4gKiBDcmVhdGVkIGJ5IGhlbiBvbiA1LzE1LzE3LlxuICovXG5cbmV4cG9ydCBjbGFzcyBVUkxIYW5kbGVyIHtcblxuICAgIHN0YXRpYyBiYXNpY1VSTCgpIHtcbiAgICAgICAgY29uc3QgdXJsX3BhdGggPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKS5zbGljZSgwLCAtMikuam9pbignLycpO1xuXG4gICAgICAgIHJldHVybiB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgKHVybF9wYXRoLmxlbmd0aCA/IHVybF9wYXRoIDogJycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlYWQgYWxsIFVSTCBwYXJhbWV0ZXJzIGludG8gYSBtYXAuXG4gICAgICogQHJldHVybnMge01hcH0gdGhlIHVybCBwYXJhbWV0ZXJzIGFzIGEga2V5LXZhbHVlIHN0b3JlIChFUzYgbWFwKVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgcGFyYW1ldGVycygpOiBvYmplY3Qge1xuICAgICAgICAvLyBBZGFwdGVkIGZyb206ICBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzIwOTA1NTEvcGFyc2UtcXVlcnktc3RyaW5nLWluLWphdmFzY3JpcHRcbiAgICAgICAgY29uc3QgcXVlcnkgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKTtcbiAgICAgICAgY29uc3QgdmFycyA9IHF1ZXJ5LnNwbGl0KCcmJyk7XG4gICAgICAgIGNvbnNvbGUubG9nKHZhcnMsIFwiLS0tIHZhcnNcIik7XG5cbiAgICAgICAgY29uc3QgdXJsUGFyYW1ldGVycyA9IHt9O1xuXG4gICAgICAgIGNvbnN0IGlzSW50ID0geCA9PiAoL15bMC05XSskLykudGVzdCh4KTtcbiAgICAgICAgY29uc3QgaXNGbG9hdCA9IHggPT4gKC9eWzAtOV0rXFwuWzAtOV0qJC8pLnRlc3QoeCk7XG5cbiAgICAgICAgY29uc3QgdHlwZUNhc3QgPSB2YWwgPT4ge1xuICAgICAgICAgICAgaWYgKGlzSW50KHZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLnBhcnNlSW50KHZhbCwgMTApO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0Zsb2F0KHZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTnVtYmVyLnBhcnNlRmxvYXQodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGVsc2U6XG4gICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9XG5cblxuICAgICAgICB2YXJzLmZvckVhY2godiA9PiB7XG4gICAgICAgICAgICBpZiAodi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3BsaXRzID0gdi5zcGxpdCgnPScpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGRlY29kZVVSSUNvbXBvbmVudChzcGxpdHNbMF0pO1xuICAgICAgICAgICAgICAgIGxldCByYXdfdmFsdWUgPSBkZWNvZGVVUklDb21wb25lbnQoc3BsaXRzWzFdKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGlzQXJyYXkgPSByYXdfdmFsdWUuc3RhcnRzV2l0aCgnLi4nKTtcbiAgICAgICAgICAgICAgICBpZiAoaXNBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICByYXdfdmFsdWUgPSByYXdfdmFsdWUuc2xpY2UoMik7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJhd192YWx1ZS5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHVybFBhcmFtZXRlcnNba2V5XSA9IGlzQXJyYXkgPyBbXSA6ICcnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICB1cmxQYXJhbWV0ZXJzW2tleV0gPSByYXdfdmFsdWUuc3BsaXQoJywnKVxuICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCh2YWwgPT4gdHlwZUNhc3QodmFsKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdXJsUGFyYW1ldGVyc1trZXldID0gdHlwZUNhc3QocmF3X3ZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB1cmxQYXJhbWV0ZXJzO1xuXG4gICAgfVxuXG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZXMgYW4gVVJMIHN0cmluZyBmcm9tIGEgbWFwIG9mIHVybCBwYXJhbWV0ZXJzXG4gICAgICogQHBhcmFtIHt7fX0gdXJsUGFyYW1ldGVycyAtIHRoZSBtYXAgb2YgcGFyYW1ldGVyc1xuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gYW4gVVJJIHN0cmluZ1xuICAgICAqL1xuICAgIHN0YXRpYyB1cmxTdHJpbmcodXJsUGFyYW1ldGVyczogb2JqZWN0KSB7XG4gICAgICAgIGNvbnN0IGF0dHIgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXModXJsUGFyYW1ldGVycykuZm9yRWFjaChrID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHYgPSB1cmxQYXJhbWV0ZXJzW2tdO1xuICAgICAgICAgICAgaWYgKHYgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IHY7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodikpIHZhbHVlID0gJy4uJyArIHYuam9pbignLCcpO1xuICAgICAgICAgICAgICAgIGF0dHIucHVzaChlbmNvZGVVUkkoayArICc9JyArIHZhbHVlKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cblxuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWU7XG4gICAgICAgIGxldCByZXMgPSB1cmwuc3Vic3RyaW5nKHVybC5sYXN0SW5kZXhPZignLycpICsgMSk7XG4gICAgICAgIGlmIChhdHRyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJlcyArPSAnPycgKyBhdHRyLmpvaW4oJyYnKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBzdGF0aWMgdXBkYXRlVVJMUGFyYW0oa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBhbnlbXSwgYWRkVG9Ccm93c2VySGlzdG9yeSA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBhcmFtcyA9IFVSTEhhbmRsZXIucGFyYW1ldGVycztcbiAgICAgICAgY3VycmVudFBhcmFtc1trZXldID0gdmFsdWU7XG4gICAgICAgIFVSTEhhbmRsZXIudXBkYXRlVXJsKGN1cnJlbnRQYXJhbXMsIGFkZFRvQnJvd3Nlckhpc3RvcnkpO1xuICAgIH1cblxuICAgIC8vIC8qKlxuICAgIC8vICAqIEdlbmVyYXRlcyBhIGtleS12YWx1ZSBtYXAgb2YgYWxsIFVSTCBwYXJhbXMgYW5kIHJlcGxhY2VzIHJlcGxhY2VLZXlzXG4gICAgLy8gICogQHBhcmFtIHVwZGF0ZUtleXNcbiAgICAvLyAgKi9cbiAgICAvLyBzdGF0aWMgdXBkYXRlVVJMUGFyYW1zKHVwZGF0ZUtleXMpIHtcbiAgICAvLyAgICAgY29uc3QgY3VycmVudFBhcmFtcyA9IFVSTEhhbmRsZXIucGFyYW1ldGVycztcbiAgICAvLyAgICAgT2JqZWN0LmtleXModXBkYXRlS2V5cykuZm9yRWFjaCgoaykgPT4gY3VycmVudFBhcmFtc1trXSA9IHVwZGF0ZUtleXNba10pXG4gICAgLy8gICAgIHJldHVybiBjdXJyZW50UGFyYW1zO1xuICAgIC8vIH1cblxuXG4gICAgc3RhdGljIHVwZGF0ZVVybCh1cmxQYXJhbWV0ZXJzOiBvYmplY3QsIGFkZFRvQnJvd3Nlckhpc3RvcnkgPSB0cnVlKSB7XG4gICAgICAgIGlmIChhZGRUb0Jyb3dzZXJIaXN0b3J5KSB7XG4gICAgICAgICAgICB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUodXJsUGFyYW1ldGVycywgJycsXG4gICAgICAgICAgICAgICAgVVJMSGFuZGxlci51cmxTdHJpbmcodXJsUGFyYW1ldGVycykpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3aW5kb3cuaGlzdG9yeS5yZXBsYWNlU3RhdGUodXJsUGFyYW1ldGVycywgJycsXG4gICAgICAgICAgICAgICAgVVJMSGFuZGxlci51cmxTdHJpbmcodXJsUGFyYW1ldGVycykpXG4gICAgICAgIH1cbiAgICB9XG5cbn0iLCJpbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjtcbmltcG9ydCB7IEJhc2VUeXBlIH0gZnJvbSBcImQzXCI7XG5cbi8qKlxuICogQ3JlYXRlZCBieSBoZW4gb24gNS8xNS8xNy5cbiAqIE1vZGlmeWVkIGJ5IGhvbyBvbiA0LzE2LzE5LlxuICovXG5sZXQgdGhlX3VuaXF1ZV9pZF9jb3VudGVyID0gMDtcblxuZXhwb3J0IGNsYXNzIFV0aWwge1xuICAgIHN0YXRpYyBzaW1wbGVVSWQoeyBwcmVmaXggPSAnJyB9KTogc3RyaW5nIHtcbiAgICAgICAgdGhlX3VuaXF1ZV9pZF9jb3VudGVyICs9IDE7XG5cbiAgICAgICAgcmV0dXJuIHByZWZpeCArIHRoZV91bmlxdWVfaWRfY291bnRlcjtcbiAgICB9XG59XG5cbmV4cG9ydCB0eXBlIEQzU2VsID0gZDMuU2VsZWN0aW9uPGFueSwgYW55LCBhbnksIGFueT5cblxuLyoqXG4gKiBTZWxlY3Rpb24gdXRpbGl0eSBmdW5jdGlvbnMgc2hvdWxkIGJlIHN0YXRpYyBtZXRob2RzIGluIHRoZSBiZWxvdyBjbGFzc1xuICovXG5leHBvcnQgY2xhc3MgU2VsIHtcbiAgICBzdGF0aWMgc2V0U2VsVmlzaWJsZSA9ICh4OiBEM1NlbCkgPT4geC5hdHRyKFwidmlzaWJpbGl0eVwiLCBcInZpc2libGVcIilcbiAgICBzdGF0aWMgc2V0U2VsSGlkZGVuID0gKHg6IEQzU2VsKSA9PiB4LmF0dHIoXCJ2aXNpYmlsaXR5XCIsIFwiaGlkZGVuXCIpXG4gICAgc3RhdGljIHNldFZpc2libGUgPSAoeDogc3RyaW5nKSA9PiBTZWwuc2V0U2VsVmlzaWJsZShkMy5zZWxlY3RBbGwoeCkpXG4gICAgc3RhdGljIHNldEhpZGRlbiA9ICh4OiBzdHJpbmcpID0+IFNlbC5zZXRTZWxIaWRkZW4oZDMuc2VsZWN0QWxsKHgpKVxuICAgIHN0YXRpYyBoaWRlRWxlbWVudCA9IChoRTogRDNTZWwpID0+IGhFLnRyYW5zaXRpb24oKS5zdHlsZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnb3BhY2l0eSc6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwb2ludGVyLWV2ZW50cyc6ICdub25lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2Rpc3BsYXknOiAnbm9uZSd9KVxuICAgIHN0YXRpYyB1bmhpZGVFbGVtZW50ID0gKGhFOiBEM1NlbCkgPT4gaEUudHJhbnNpdGlvbigpLnN0eWxlcyh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdvcGFjaXR5JzogMSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwb2ludGVyLWV2ZW50cyc6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkaXNwbGF5JzogbnVsbH0pXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9vc2VPYmplY3Qge1xuICAgIFtrZXk6IHN0cmluZ106IGFueVxufVxuXG5leHBvcnQgdHlwZSBkM1M8VCBleHRlbmRzIEJhc2VUeXBlLCBVID0gYW55PiA9IGQzLlNlbGVjdGlvbjxULCBVLCBhbnksIGFueT4iLCJpbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCdcblxuZnVuY3Rpb24gYXNjT3JkZXIobjEsIG4yKSB7XG4gICAgaWYgKG4xIDwgbjIpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICBlbHNlIGlmIChuMSA+IG4yKSB7IFxuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG5cbmV4cG9ydCB7ZmluZEFsbEluZGV4ZXMsIGluc2VydEF0Xywgb3JkZXJlZEluc2VydF8sIHNldDJTb3J0ZWRBcnJheX1cblxuLyoqXG4gKiBGaW5kIGFsbCBpbmRleGVzIHRoYXQgbWF0Y2ggYSBwYXJ0aWN1bGFyIHByZWRpY2F0ZVxuICovXG5mdW5jdGlvbiBmaW5kQWxsSW5kZXhlczxUPihhcnJheTpBcnJheTxUPiwgcHJlZGljYXRlOihhOlQpID0+IGJvb2xlYW4pOiBudW1iZXJbXSB7XG4gICAgbGV0IGZyb21JbmRleD0wO1xuICAgIGxldCByZXN1bHRzID0gW107XG5cbiAgICBsZXQgaSA9IF8uZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCk7XG4gICAgd2hpbGUgKGkgIT0gLTEpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKGkpO1xuICAgICAgICBpID0gXy5maW5kSW5kZXgoYXJyYXksIHByZWRpY2F0ZSwgaSsxKVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzO1xufTtcblxuZnVuY3Rpb24gaW5zZXJ0QXRfPFQ+KGFycmF5OkFycmF5PFQ+LCB2YWw6VCwgaW5kOm51bWJlcik6QXJyYXk8VD4ge1xuICAgIGFycmF5LnNwbGljZShpbmQsIDAsIHZhbCk7XG4gICAgcmV0dXJuIGFycmF5XG59XG5cbi8qKlxuICogQ29udmVydCBhIHNldCB0byBhbiBvcmRlcmVkIGFycmF5XG4gKi9cbmZ1bmN0aW9uIHNldDJTb3J0ZWRBcnJheTxUPihpbnB1dDpTZXQ8VD4pOkFycmF5PFQ+IHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShpbnB1dCkuc29ydChhc2NPcmRlcilcbn1cblxuLyoqXG4gKiBJbnNlcnQgYSB2YWx1ZSBpbnRvIGFycmF5IGluIHNvcnRlZCBvcmRlciBJTiBQTEFDRVxuICogXG4gKiBXQVJOSU5HOiBPbmx5IGhhbmRsZXMgbnVtYmVycywgc29ydGVkIGZyb20gbGVhc3QgdG8gZ3JlYXRlc3RcbiAqIC0gQXNzdW1lcyBhbHJlYWR5IHNvcnRlZCBhcnJheVxuICovXG5mdW5jdGlvbiBvcmRlcmVkSW5zZXJ0XzxUPihhcnJheTpBcnJheTxUPiwgdmFsOlQsIGNvbGRzdGFydD1mYWxzZSk6QXJyYXk8VD4ge1xuICAgIC8vIFJlc29ydCBhcnJheSBpZiBkZXNpcmVkXG4gICAgaWYgKGNvbGRzdGFydCkge1xuICAgICAgICBhcnJheS5zb3J0KGFzY09yZGVyKVxuICAgIH1cblxuICAgIGNvbnN0IGluZCA9IF8uc29ydGVkSW5kZXgoYXJyYXksIHZhbCk7XG4gICAgcmV0dXJuIGluc2VydEF0XyhhcnJheSwgdmFsLCBpbmQpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYWtlUmFuZG9tKGxlbjpudW1iZXIpe1xuICBjb25zdCBhOm51bWJlcltdID0gbmV3IEFycmF5KGxlbikuZmlsbCgwKVxuXG4gIHJldHVybiBhLm1hcCgoeCkgPT4ge3JldHVybiBfLnJhbmRvbSgtNSwgNSwgdHJ1ZSl9KVxufSIsIi8qKlxuICogQ29udmVydCBhIEpTIG9iamVjdCBpbnRvIEdFVCBVUkwgcGFyYW1ldGVyc1xuICogXG4gKiBAcGFyYW0gYmFzZSBCYXNlIFVSTCBhdG9wIHdoaWNoIHRvIGFkZCBHRVQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHBhcmFtcyBPYmplY3QgdG8gaW5zZXJ0IGludG8gYSBVUkwgc3RyaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlVXJsKGJhc2U6IHN0cmluZywgcGFyYW1zPzogb2JqZWN0KTpzdHJpbmcge1xuICAgIGlmIChwYXJhbXMpe1xuICAgICAgICBsZXQgb3V0OiBzdHJpbmcgPSBiYXNlICsgXCI/XCI7XG5cbiAgICAgICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKCBrID0+IHtcbiAgICAgICAgICAgIG91dCArPSBrO1xuICAgICAgICAgICAgb3V0ICs9ICc9JztcbiAgICAgICAgICAgIG91dCArPSBwYXJhbXNba107XG4gICAgICAgICAgICBvdXQgKz0gXCImXCI7XG4gICAgICAgIH0pXG4gICAgICAgIHJldHVybiBvdXQucmVwbGFjZSgvJiQvZywgXCJcIik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gYmFzZTtcbiAgICB9XG59O1xuXG4vKipcbiAqIENvbnZlcnQgaW5mb3JtYXRpb24gaW4gR0VUIHJlcXVlc3QgaW50byB0aGUgbWVzc2FnZSBmb3IgYSBQT1NUIHJlcXVlc3QgICAgXG4gKi9cbmV4cG9ydCBjb25zdCB0b1BheWxvYWQgPSAodG9TZW5kKSA9PiB7cmV0dXJuIHtcbiAgICBtZXRob2Q6XCJQT1NUXCIsXG4gICAgYm9keTpKU09OLnN0cmluZ2lmeSh0b1NlbmQpLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIFwiQ29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOFwiXG4gICAgICAgIH1cbn19IiwiLy8gW1t2YWwsIGluZF0sIFt2YWwsIGluZF0uLi5dXG50eXBlIENvbXBGbkluZCA9IChhOm51bWJlcltdLCBiOm51bWJlcltdKSA9PiBudW1iZXI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU29ydEFycmF5IHtcbiAgICBhcnI6IG51bWJlcltdLFxuICAgIHNvcnRJbmRpY2VzOiBudW1iZXJbXSxcbn1cblxuLyoqXG4gKiBDb3BpZXMgYW5kIHNvcnRzIGFuIGFycmF5IHdoaWxlIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGluZGljZXMuIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIHNvcnRpbmcgbWF4IC0+IG1pbi5cbiAqIFxuICogQHBhcmFtIGFyciAtIEFycmF5IHRvIGJlIGNvcGllZCBhbmQgc29ydGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb3J0V2l0aEluZGljZXMoYXJyOm51bWJlcltdLCBmbj86Q29tcEZuSW5kKTogU29ydEFycmF5IHtcbiAgICAvLyBJZiBmbiBpcyBub3QgcHJvdmlkZWQsIGRlZmF1bHQgdG8gc29ydGluZyBieSBtYXggdmFsdWVcbiAgICBpZiAoIWZuKSB7XG4gICAgICAgIGZuID0gZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgICAgcmV0dXJuIGxlZnRbMF0gPiByaWdodFswXSA/IC0xIDogMTtcbiAgICAgICAgfSBcbiAgICB9XG5cbiAgICBsZXQgb3V0OlNvcnRBcnJheSA9IHtcbiAgICAgICAgYXJyOiBbXSxcbiAgICAgICAgc29ydEluZGljZXM6IFtdXG4gICAgfTtcblxuICAgIGxldCBpZHhUcmFja2VyOiBudW1iZXJbXVtdID0gW11cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgaWR4VHJhY2tlcltpXSA9IFthcnJbaV0sIGldO1xuICAgIH1cblxuICAgIGlkeFRyYWNrZXIuc29ydChmdW5jdGlvbihsZWZ0LCByaWdodCkge1xuICAgICAgcmV0dXJuIGxlZnRbMF0gPiByaWdodFswXSA/IC0xIDogMTtcbiAgICB9KTtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgYXJyLmxlbmd0aDsgaisrKSB7XG4gICAgICBvdXQuc29ydEluZGljZXMucHVzaChpZHhUcmFja2VyW2pdWzFdKTtcbiAgICAgIG91dC5hcnJbal0gPSBpZHhUcmFja2VyW2pdWzBdO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG4gIH0iLCIvLyBDb2xvcnMgd2VyZSBnZW5lcmF0ZWQgdG8gYmUgYXMgdmlzdWFsbHkgZGlzdGluY3QgYXMgcG9zc2libGUgYnk6IGh0dHA6Ly9qbm5ubm4uZ2l0aHViLmlvL2NhdGVnb3J5LWNvbG9ycy1jb25zdHJhaW5lZC5odG1sXG5leHBvcnQgY29uc3QgQ09MT1JTMjAwID0gW1xuICAgIFwiIzM5NTdmZlwiLCBcIiNkM2ZlMTRcIiwgXCIjYzkwODBhXCIsIFwiI2ZlYzdmOFwiLCBcIiMwYjdiM2VcIiwgXCIjMGJmMGU5XCIsIFwiI2MyMDNjOFwiLCBcIiNmZDliMzlcIiwgXG4gICAgXCIjODg4NTkzXCIsIFwiIzkwNjQwN1wiLCBcIiM5OGJhN2ZcIiwgXCIjZmU2Nzk0XCIsIFwiIzEwYjBmZlwiLCBcIiNhYzdiZmZcIiwgXCIjZmVlN2MwXCIsIFwiIzk2NGM2M1wiLFxuICAgIFwiIzFkYTQ5Y1wiLCBcIiMwYWQ4MTFcIiwgXCIjYmJkOWZkXCIsIFwiI2ZlNmNmZVwiLCBcIiMyOTcxOTJcIiwgXCIjZDFhMDljXCIsIFwiIzc4NTc5ZVwiLCBcIiM4MWZmYWRcIixcbiAgICBcIiM3Mzk0MDBcIiwgXCIjY2E2OTQ5XCIsIFwiI2Q5YmYwMVwiLCBcIiM2NDZhNThcIiwgXCIjZDUwOTdlXCIsIFwiI2JiNzNhOVwiLCBcIiNjY2Y2ZTlcIiwgXCIjOWNiNGI2XCIsXG4gICAgXCIjYjZhN2Q0XCIsIFwiIzllOGM2MlwiLCBcIiM2ZTgzYzhcIiwgXCIjMDFhZjY0XCIsIFwiI2E3MWFmZFwiLCBcIiNjZmU1ODlcIiwgXCIjZDRjY2QxXCIsIFwiI2ZkNDEwOVwiLFxuICAgIFwiI2JmOGYwZVwiLCBcIiMyZjc4NmVcIiwgXCIjNGVkMWE1XCIsIFwiI2Q4YmI3ZFwiLCBcIiNhNTQ1MDlcIiwgXCIjNmE5Mjc2XCIsIFwiI2E0Nzc3YVwiLCBcIiNmYzEyYzlcIixcbiAgICBcIiM2MDZmMTVcIiwgXCIjM2NjNGQ5XCIsIFwiI2YzMWM0ZVwiLCBcIiM3MzYxNmZcIiwgXCIjZjA5N2M2XCIsIFwiI2ZjODc3MlwiLCBcIiM5MmE2ZmVcIiwgXCIjODc1YjQ0XCIsXG4gICAgXCIjNjk5YWIzXCIsIFwiIzk0YmMxOVwiLCBcIiM3ZDViZjBcIiwgXCIjZDI0ZGZlXCIsIFwiI2M4NWI3NFwiLCBcIiM2OGZmNTdcIiwgXCIjYjYyMzQ3XCIsIFwiIzk5NGI5MVwiLFxuICAgIFwiIzY0NmI4Y1wiLCBcIiM5NzdhYjRcIiwgXCIjZDY5NGZkXCIsIFwiI2M0ZDViNVwiLCBcIiNmZGM0YmRcIiwgXCIjMWNhZTA1XCIsIFwiIzdiZDk3MlwiLCBcIiNlOTcwMGFcIixcbiAgICBcIiNkMDhmNWRcIiwgXCIjOGJiOWUxXCIsIFwiI2ZkZTk0NVwiLCBcIiNhMjlkOThcIiwgXCIjMTY4MmZiXCIsIFwiIzlhZDllMFwiLCBcIiNkNmNhZmVcIiwgXCIjOGQ4MzI4XCIsXG4gICAgXCIjYjA5MWE3XCIsIFwiIzY0NzU3OVwiLCBcIiMxZjhkMTFcIiwgXCIjZTdlYWZkXCIsIFwiI2I5NjYwYlwiLCBcIiNhNGE2NDRcIiwgXCIjZmVjMjRjXCIsIFwiI2IxMTY4Y1wiLFxuICAgIFwiIzE4OGNjMVwiLCBcIiM3YWIyOTdcIiwgXCIjNDQ2OGFlXCIsIFwiI2M5NDlhNlwiLCBcIiNkNDgyOTVcIiwgXCIjZWI2ZGMyXCIsIFwiI2Q1YjBjYlwiLCBcIiNmZjlmZmJcIixcbiAgICBcIiNmZGIwODJcIiwgXCIjYWY0ZDQ0XCIsIFwiI2E3NTljNFwiLCBcIiNhOWUwM2FcIiwgXCIjMGQ5MDZiXCIsIFwiIzllZTNiZFwiLCBcIiM1Yjg4NDZcIiwgXCIjMGQ4OTk1XCIsXG4gICAgXCIjZjI1YzU4XCIsIFwiIzcwYWU0ZlwiLCBcIiM4NDdmNzRcIiwgXCIjOTA5NGJiXCIsIFwiI2ZmZTJmMVwiLCBcIiNhNjcxNDlcIiwgXCIjOTM2YzhlXCIsIFwiI2QwNDkwN1wiLFxuICAgIFwiI2MzYjhhNlwiLCBcIiNjZWY4YzRcIiwgXCIjN2E5MjkzXCIsIFwiI2ZkYTJhYlwiLCBcIiMyZWY2YzVcIiwgXCIjODA3MjQyXCIsIFwiI2NiOTRjY1wiLCBcIiNiNmJkZDBcIixcbiAgICBcIiNiNWM3NWRcIiwgXCIjZmRlMTg5XCIsIFwiI2I3ZmY4MFwiLCBcIiNmYTJkOGVcIiwgXCIjODM5YTVmXCIsIFwiIzI4YzJiNVwiLCBcIiNlNWU5ZTFcIiwgXCIjYmM3OWQ4XCIsXG4gICAgXCIjN2VkOGZlXCIsIFwiIzlmMjBjM1wiLCBcIiM0ZjdhNWJcIiwgXCIjZjUxMWZkXCIsIFwiIzA5Yzk1OVwiLCBcIiNiY2QwY2VcIiwgXCIjODY4NWZkXCIsIFwiIzk4ZmNmZlwiLFxuICAgIFwiI2FmYmZmOVwiLCBcIiM2ZDY5YjRcIiwgXCIjNWY5OWZkXCIsIFwiI2FhYTg3ZVwiLCBcIiNiNTlkZmJcIiwgXCIjNWQ4MDlkXCIsIFwiI2Q5YTc0MlwiLCBcIiNhYzVjODZcIixcbiAgICBcIiM5NDY4ZDVcIiwgXCIjYTRhMmIyXCIsIFwiI2IxMzc2ZVwiLCBcIiNkNDNmM2RcIiwgXCIjMDVhOWQxXCIsIFwiI2MzODM3NVwiLCBcIiMyNGI1OGVcIiwgXCIjNmVhYmFmXCIsXG4gICAgXCIjNjZiZjdmXCIsIFwiIzkyY2JiYlwiLCBcIiNkZGIxZWVcIiwgXCIjMWJlODk1XCIsIFwiI2M3ZWNmOVwiLCBcIiNhNmJhYTZcIiwgXCIjODA0NWNkXCIsIFwiIzVmNzBmMVwiLFxuICAgIFwiI2E5ZDc5NlwiLCBcIiNjZTYyY2JcIiwgXCIjMGU5NTRkXCIsIFwiI2E5N2QyZlwiLCBcIiNmY2I4ZDNcIiwgXCIjOWJmZWUzXCIsIFwiIzRlOGQ4NFwiLCBcIiNmYzZkM2ZcIixcbiAgICBcIiM3YjlmZDRcIiwgXCIjOGM2MTY1XCIsIFwiIzcyODA1ZVwiLCBcIiNkNTM3NjJcIiwgXCIjZjAwYTFiXCIsIFwiI2RlNWM5N1wiLCBcIiM4ZWEyOGJcIiwgXCIjZmNjZDk1XCIsXG4gICAgXCIjYmE5YzU3XCIsIFwiI2I3OWE4MlwiLCBcIiM3YzVhODJcIiwgXCIjN2Q3Y2E0XCIsIFwiIzk1OGFkNlwiLCBcIiNjZDgxMjZcIiwgXCIjYmRiMGI3XCIsIFwiIzEwZTBmOFwiLFxuICAgIFwiI2RjY2M2OVwiLCBcIiNkNmRlMGZcIiwgXCIjNjE2ZDNkXCIsIFwiIzk4NWEyNVwiLCBcIiMzMGM3ZmRcIiwgXCIjMGFlYjY1XCIsIFwiI2UzY2RiNFwiLCBcIiNiZDFiZWVcIixcbiAgICBcIiNhZDY2NWRcIiwgXCIjZDc3MDcwXCIsIFwiIzhlYTViOFwiLCBcIiM1YjVhZDBcIiwgXCIjNzY2NTVlXCIsIFwiIzU5ODEwMFwiLCBcIiM4Njc1N2VcIiwgXCIjNWVhMDY4XCIsXG5dIiwiaW1wb3J0IHsgRDNTZWwgfSBmcm9tIFwiLi9VdGlsXCJcblxuLyoqXG4gKiBBVFRFTlRJT04gUkVTUE9OU0VTIEZST00gQkFDS0VORFxuICpcbiAqIENvbnRhaW4gdGhlIGF0dGVudGlvbnMgYW5kIGVtYmVkZGluZ3MgZm9yIGFsbCBjb21iaW5hdGlvbnMgb2YgcmV0dXJucyBmcm9tIHRoZSBiYWNrZW5kXG4gKi9cblxuZXhwb3J0IHR5cGUgTW9kZWxJbmZvID0ge1xuICAgIG5sYXllcnM6IG51bWJlclxuICAgIG5oZWFkczogbnVtYmVyXG59XG5cbnR5cGUgQWJzdHJhY3RBdHRlbnRpb25SZXNwb25zZTxUPiA9IHtcbiAgICBhYTogVFxufVxuXG4vKipcbiAqIEFUVEVOVElPTiBSRVNVTFRTIEZST00gQkFDS0VORFxuICpcbiAqIFRoZXNlIGFyZSB0aGUgcmVzdWx0cyB0aGF0IGFyZSBlbmNhc2VkIGluIHRoZSAnYWEnIGFuZCAnYWInIGtleXMgcmV0dXJuZWRcbiAqL1xuZXhwb3J0IHR5cGUgQXR0ZW50aW9uUmVzcG9uc2UgPSBBYnN0cmFjdEF0dGVudGlvblJlc3BvbnNlPEF0dGVudGlvbk1ldGFSZXN1bHQ+XG5leHBvcnQgdHlwZSBBdHRlbnRpb25NZXRhUmVzdWx0ID0gQWJzdHJhY3RBdHRlbnRpb25SZXN1bHQ8RnVsbFNpbmdsZVRva2VuSW5mb1tdPlxuXG5leHBvcnQgdHlwZSBGdWxsU2luZ2xlVG9rZW5JbmZvID0ge1xuICAgIHRleHQ6IHN0cmluZyxcbiAgICBlbWJlZGRpbmdzOiBudW1iZXJbXSxcbiAgICBjb250ZXh0czogbnVtYmVyW10sXG4gICAgYnBlX3Rva2VuOiBzdHJpbmcsXG4gICAgYnBlX3Bvczogc3RyaW5nLFxuICAgIGJwZV9kZXA6IHN0cmluZyxcbiAgICBicGVfaXNfZW50OiBib29sZWFuLFxuICAgIHRvcGtfd29yZHM6IHN0cmluZ1tdLFxuICAgIHRvcGtfcHJvYnM6IG51bWJlcltdXG59XG5cbmludGVyZmFjZSBBYnN0cmFjdEF0dGVudGlvblJlc3VsdDxUPiB7XG4gICAgYXR0OiBudW1iZXJbXVtdW10sXG4gICAgbGVmdDogVCxcbiAgICByaWdodDogVCxcbn1cblxuLyoqXG4gKiBTRUFSQ0ggUkVTVUxUIFRZUEVTXG4gKi9cblxuaW50ZXJmYWNlIE1hdGNoZWRUb2tBdHQge1xuICAgIGF0dDogbnVtYmVyW11cbiAgICBvZmZzZXRfdG9fbWF4OiBudW1iZXJcbiAgICBsb2Nfb2ZfbWF4OiBudW1iZXJcbn1cblxuXG5pbnRlcmZhY2UgTWF0Y2hlZEF0dGVudGlvbnMge1xuICAgIGluOiBNYXRjaGVkVG9rQXR0LFxuICAgIG91dDogTWF0Y2hlZFRva0F0dCxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGYWlzc1NlYXJjaFJlc3VsdHMge1xuICAgIHNlbnRlbmNlOiBzdHJpbmdcbiAgICBpbmRleDogbnVtYmVyXG4gICAgbmV4dF9pbmRleDogbnVtYmVyXG4gICAgbWF0Y2g6IHN0cmluZ1xuICAgIG1hdGNoX3BsdXNfMTogc3RyaW5nXG4gICAgbWF0Y2hlZF9hdHQ6IE1hdGNoZWRBdHRlbnRpb25zXG4gICAgbWF0Y2hlZF9hdHRfcGx1c18xOiBNYXRjaGVkQXR0ZW50aW9uc1xuICAgIHRva2VuczogVG9rZW5GYWlzc01hdGNoW11cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUb2tlbkZhaXNzTWF0Y2gge1xuICAgIHRva2VuOiBzdHJpbmdcbiAgICBwb3M6IHN0cmluZ1xuICAgIGRlcDogc3RyaW5nXG4gICAgaXNfZW50OiBzdHJpbmdcbiAgICBpc19tYXRjaDogYm9vbGVhblxuICAgIGlzX25leHRfd29yZDogYm9vbGVhblxuICAgIGlud2FyZDogbnVtYmVyW11cbiAgICBvdXR3YXJkOiBudW1iZXJbXVxufVxuXG4vKipcbiAqIEVWRU5UIFRZUEVTXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5FdmVudCB7XG4gICAgc2VsPzogRDNTZWwsXG4gICAgc2lkZTogU2lkZU9wdGlvbnMsXG4gICAgaW5kOiBudW1iZXIgfCBcIm51bGxcIixcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUb2tlbkVtYmVkZGluZ0V2ZW50IGV4dGVuZHMgVG9rZW5FdmVudCB7XG4gICAgZW1iZWRkaW5nczogbnVtYmVyW11cbn1cblxuZXhwb3J0IHR5cGUgSGVhZEJveEV2ZW50ID0ge1xuICAgIHNpZGU6IFNpZGVPcHRpb25zLFxuICAgIGluZDogbnVtYmVyLFxuICAgIGhlYWQ6IG51bWJlcixcbn1cblxuLyoqXG4gKiBNSVNDRUxMQU5FT1VTIFRZUEVTXG4gKi9cblxuZXhwb3J0IHR5cGUgU2VudGVuY2VPcHRpb25zID0gXCJhYlwiIHwgXCJiYVwiIHwgXCJhYVwiIHwgXCJiYlwiIHwgXCJhbGxcIjtcbmV4cG9ydCB0eXBlIFNpZGVPcHRpb25zID0gXCJsZWZ0XCIgfCBcInJpZ2h0XCJcbmV4cG9ydCB0eXBlIFNpbXBsZU1ldGEgPSBcInBvc1wiIHwgXCJkZXBcIiB8IFwiaXNfZW50XCJcbmV4cG9ydCB0eXBlIFRva2VuT3B0aW9ucyA9IFwiYVwiIHwgXCJiXCIgfCBcImFsbFwiXG5cbmV4cG9ydCBlbnVtIFRvZ2dsZWQge1xuICAgIEFEREVEID0gMCxcbiAgICBSRU1PVkVELFxufVxuXG5leHBvcnQgZW51bSBOb3JtQnkge1xuICAgIFJvdyA9IDAsXG4gICAgQ29sLFxuICAgIEFsbFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFic3RyYWN0TWV0YU9wdGlvbnMge1xuICAgIHBvczogc3RyaW5nW10sXG4gICAgZGVwOiBzdHJpbmdbXSxcbiAgICBpc19lbnQ6IGFueSxcbiAgICBlbnRzOiBzdHJpbmdbXSxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNZXRhT3B0aW9ucyBleHRlbmRzIEFic3RyYWN0TWV0YU9wdGlvbnMge1xuICAgIGlzX2VudDogYm9vbGVhbltdLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbG9yTWV0YU9wdGlvbnMgZXh0ZW5kcyBBYnN0cmFjdE1ldGFPcHRpb25zIHtcbiAgICBpc19lbnQ6IHN0cmluZ1tdIC8vIFJlcHJlc2VudGluZyBoZXggY29sb3JzXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29sb3JNZXRhU2NhbGUge1xuICAgIHBvczogKGQ6IHN0cmluZykgPT4gc3RyaW5nLFxuICAgIGRlcDogKGQ6IHN0cmluZykgPT4gc3RyaW5nLFxuICAgIGlzX2VudDogKGQ6IHN0cmluZykgPT4gc3RyaW5nLFxuICAgIGVudHM6IChkOiBzdHJpbmcpID0+IHN0cmluZyxcbiAgICBvZmZzZXQ/OiAoZDogc3RyaW5nKSA9PiBzdHJpbmcsXG59XG5cbmV4cG9ydCBlbnVtIE1vZGVsS2luZCB7XG4gICAgQmlkaXJlY3Rpb25hbCA9IFwiYmlkaXJlY3Rpb25hbFwiLFxuICAgIEF1dG9yZWdyZXNzaXZlID0gXCJhdXRvcmVncmVzc2l2ZVwiXG59IiwiaW1wb3J0ICogYXMgZDMgZnJvbSAnZDMnXG5cbmQzLnNlbGVjdGlvbi5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHsgIFxuICAgIHRoaXMuc2VsZWN0QWxsKCcqJykucmVtb3ZlKCk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbmQzLnNlbGVjdGlvbi5wcm90b3R5cGUudG9nZ2xlQ2xhc3MgPSBmdW5jdGlvbihjbGFzc05hbWUpIHsgIFxuICAgIHRoaXMuY2xhc3NlZChjbGFzc05hbWUsICF0aGlzLmNsYXNzZWQoY2xhc3NOYW1lKSk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbmQzLnNlbGVjdGlvbi5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkgeyAgXG4gICAgdGhpcy5zdHlsZSgnZGlzcGxheScsICdpbml0aWFsJyk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbmQzLnNlbGVjdGlvbi5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uKCkgeyAgXG4gICAgdGhpcy5zdHlsZSgnZGlzcGxheScsICdub25lJyk7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cbmQzLnNlbGVjdGlvbi5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7ICBcbiAgICB2YXIgaXNIaWRkZW4gPSB0aGlzLnN0eWxlKCdkaXNwbGF5JykgPT0gJ25vbmUnO1xuICAgIHJldHVybiB0aGlzLnN0eWxlKCdkaXNwbGF5JywgaXNIaWRkZW4gPyAnaW5oZXJpdCcgOiAnbm9uZScpO1xufVxuXG5kMy5zZWxlY3Rpb24ucHJvdG90eXBlLmFmdGVyID0gZnVuY3Rpb24odGFnTmFtZSkgeyAgXG4gICAgdmFyIGVsZW1lbnRzID0gW107XG4gIFxuICAgIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcbiAgICAgIHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgdGhpcy5uZXh0U2libGluZyk7XG4gICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgIH0pO1xuICBcbiAgICByZXR1cm4gZDMuc2VsZWN0QWxsKGVsZW1lbnRzKTtcbiAgfVxuXG5kMy5zZWxlY3Rpb24ucHJvdG90eXBlLmJlZm9yZSA9IGZ1bmN0aW9uKHRhZ05hbWUpIHsgIFxuICAgIHZhciBlbGVtZW50cyA9IFtdO1xuICBcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgICB0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIHRoaXMpO1xuICAgICAgZWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICB9KTtcbiAgXG4gICAgcmV0dXJuIGQzLnNlbGVjdEFsbChlbGVtZW50cyk7XG59IiwiaW1wb3J0ICogYXMgUiBmcm9tICdyYW1kYSdcblxuLyoqXG4gKiBNYXAgYSBsaXN0IGFzIHZhbHVlcyB0byBhbiBvYmplY3Qgd2hvc2Uga2V5cyBhcmUgdGhlIG9yaWdpbmFsIGxpc3RcbiAqL1xuLy8gKFN0cmluZyAtPiBiKSAgLT4gW1N0cmluZ10gLT4ge1N0cmluZzogYn1cbmV4cG9ydCBjb25zdCBvYmpGcm9tS2V5cyA9IFIuY3VycnkoKGZuLCBrZXlzKSA9PiBSLnppcE9iaihrZXlzLCBSLm1hcChmbiwga2V5cykpKSBcblxuZXhwb3J0IGNvbnN0IGFzc2lnblplcm86ICh4OmFueSkgPT4gbnVtYmVyID0geCA9PiAwO1xuXG4vKipcbiAqIEdpdmVuIGFuIGxpc3QsIGNyZWF0ZSBhbiBvYmplY3Qgd2hvc2UgdmFsdWVzIGFyZSBhbGwgMFxuICovXG5leHBvcnQgY29uc3QgaW5pdFplcm8gPSBvYmpGcm9tS2V5cyhhc3NpZ25aZXJvKSIsImltcG9ydCB7IE1haW5HcmFwaGljIH0gZnJvbSAnLi92aXMvbXlNYWluJ1xuaW1wb3J0IHsgQVBJLCBlbXB0eVRva2VuRGlzcGxheSB9IGZyb20gJy4vYXBpL21haW5BcGknXG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCdcbmltcG9ydCB7IFRva2VuV3JhcHBlciB9IGZyb20gJy4vZGF0YS9Ub2tlbldyYXBwZXInXG4vLyBpbXBvcnQgeyBUZXN0ZXIgfSBmcm9tIFwiLi4vdHMvdGVzdFwiXG5cbmltcG9ydCBcIiFmaWxlLWxvYWRlcj9uYW1lPWV4QkVSVC5odG1sIS4uL2V4QkVSVC5odG1sXCI7XG5pbXBvcnQgXCIhZmlsZS1sb2FkZXI/bmFtZT1pbmRleC5odG1sIS4uL2luZGV4Lmh0bWxcIjtcbmltcG9ydCBcIi4uL2Nzcy9tYWluLnNjc3NcIlxuXG5cbmZ1bmN0aW9uIGRvTXlTdmcoKSB7XG4gICAgcmV0dXJuIG5ldyBNYWluR3JhcGhpYygpXG59O1xuXG4vKipcbiAqIENyZWF0ZSB0aGUgc3RhdGljIGZpbGVzIG5lZWRlZCBmb3IgdGhlIGRlbW8uIFNhdmUgdGhlIGtleXMgYW5kIGZpbGUgcGF0aHMgdG8gYSBqc29uIG9iamVjdCB0aGF0IGlzIHRoZW4gd3JpdHRlbiB0byBhIGZpbGVcbiAqXG4gKiBUaGlzIHdpbGwgcHJpbnQgdGhlIG9iamVjdCBhZnRlciBldmVyeSBjYWxsLiBXaGVuIHRoZSBrZXkgbGVuZ3RoIGlzIHRoZSBleHBlY3RlZCBsZW5ndGgsIHJpZ2h0IGNsaWNrIGluIGNocm9tZSBhbmQgc2VsZWN0IFwic2F2ZSBhcyBnbG9iYWwgdmFyaWFibGVcIlxuICpcbiAqIFRoZW4sIGluIHRoZSBjb25zb2xlLCB0eXBlIFwiY29weSh0ZW1wMSlcIi4gVXNlIHN1YmxpbWUgdGV4dCAoaXQgaXMgdGhlIGJlc3QgZm9yIGhhbmRsaW5nIGxhcmdlIGZpbGVzKSB0byBwYXN0ZSB0aGlzIGludG8gdGhlIGNvZGUgYW5kIHNhdmUgaXQgYXMgX19fXy5qc29uXG4gKlxuICogQHBhcmFtIHNlbnRlbmNlIC0gVGhlIHNlbnRlbmNlIHRvIGFuYWx5emVcbiAqIEBwYXJhbSBtYXNrSW5kIC0gV2hpY2ggaW5kZXggdG8gbWFzayBpbiB0aGUgc2VudGVuY2UuIEF0bSwgY2FuIG9ubHkgcmVjb3JkIG9uZSBtYXNraW5nXG4gKiBAcGFyYW0gb3V0RGljdFBhdGggLSBXaGVyZSB0byBzYXZlIHRoZSBvYmplY3Qgb2YgaGFzaGtleTogZmlsZXBhdGhcbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGVtb3Moc2VudGVuY2UsIG1hc2tJbmQ6IG51bWJlciwgbW9kZWxOYW1lOiBzdHJpbmcsIGNvcnB1c05hbWU6IHN0cmluZywgb3V0RGljdFBhdGgpIHtcbiAgICBjb25zdCBhcGkgPSBuZXcgQVBJKClcbiAgICBjb25zdCBsYXllcnMgPSBfLnJhbmdlKDEyKVxuXG4gICAgY29uc3QgTCA9IDBcblxuICAgIGNvbnN0IGNvbnRlbnRIYXNoID0ge30gICAgICAgICAgLy8gTWFwIGhhc2ggLT4gY29udGVudHNcblxuICAgIC8vIEdldCB0aGUgYmFzZSByZXR1cm4gZm9yIGFsbCBwYWdlIGluaXRpYWxpemF0aW9uc1xuICAgIF8ucmFuZ2UoMTIpLmZvckVhY2goTCA9PiB7XG4gICAgICAgIGFwaS5nZXRNZXRhQXR0ZW50aW9ucyhtb2RlbE5hbWUsIHNlbnRlbmNlLCBMLCBjb250ZW50SGFzaCkudGhlbihyMCA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b2tDYXBzdWxlID0gbmV3IFRva2VuV3JhcHBlcihyMC5wYXlsb2FkKTtcblxuICAgICAgICAgICAgLy8gVW5tYXNrZWQgcmVzcG9uc2U6XG4gICAgICAgICAgICBhcGkudXBkYXRlTWFza2VkQXR0ZW50aW9ucyhtb2RlbE5hbWUsIHRva0NhcHN1bGUuYSwgc2VudGVuY2UsIEwsIGNvbnRlbnRIYXNoKS50aGVuKHIxID0+IHtcbiAgICAgICAgICAgICAgICAvLyBNYXNrZWQgd29yZCBhbmQgc2VhcmNoaW5nIHJlc3BvbnNlczpcbiAgICAgICAgICAgICAgICB0b2tDYXBzdWxlLmEubWFzayhtYXNrSW5kKVxuICAgICAgICAgICAgICAgIGFwaS51cGRhdGVNYXNrZWRBdHRlbnRpb25zKG1vZGVsTmFtZSwgdG9rQ2Fwc3VsZS5hLCBzZW50ZW5jZSwgTCwgY29udGVudEhhc2gpLnRoZW4ocjIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBHZXQgc2VhcmNoIHJlc3VsdHMgYnkgZW1iZWRkaW5nXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZyA9IHIyWydhYSddWydsZWZ0J11bbWFza0luZF0uZW1iZWRkaW5nc1xuICAgICAgICAgICAgICAgICAgICBhcGkuZ2V0TmVhcmVzdEVtYmVkZGluZ3MobW9kZWxOYW1lLCBjb3JwdXNOYW1lLCBlbWJlZGRpbmcsIEwsIF8ucmFuZ2UoMTIpLCA1MCwgY29udGVudEhhc2gpLnRoZW4oeCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHNlYXJjaCByZXN1bHRzIGJ5IGNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHIyWydhYSddWydsZWZ0J11bbWFza0luZF0uY29udGV4dHNcbiAgICAgICAgICAgICAgICAgICAgYXBpLmdldE5lYXJlc3RDb250ZXh0cyhtb2RlbE5hbWUsIGNvcnB1c05hbWUsIGNvbnRleHQsIEwsIF8ucmFuZ2UoMTIpLCA1MCwgY29udGVudEhhc2gpLnRoZW4oeCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhPYmplY3Qua2V5cyhjb250ZW50SGFzaCkubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGNvbnRlbnRIYXNoKTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG4vKipcbiAqIFxuICogT2JzZXJ2ZSBob3cgdGhlIGRlbW8gY3JlYXRpb24gcHJvY2VzcyB3b3Jrcy5cbiAqIFxuICogSWYgZGVzaXJlZCB0byBtYXNrIG11bHRpcGxlIHdvcmRzIGluIHRoZSBpbnB1dCBmb3IgZGVtbyBwdXJwb3NlcywgdHJ5IGxvb3Bpbmcgb3ZlciB0aGUgbWFzayBpbmRzIGFuZCBtYXNraW5nIGVhY2ggb25lIGluZGl2aWR1YWxseVxuICogXG4gKiBAcGFyYW0gc2VudGVuY2UgVGhlIGRlbW8gc2VudGVuY2VcbiAqIEBwYXJhbSBtYXNrSW5kIERlc2lyZWQgaW5kZXggdG8gbWFzayAoY2FuIGN1cnJlbnRseSBvbmx5IGFjY2VwdCBhIHNpbmdsZSBtYXNrIGluZGV4KVxuICogQHBhcmFtIG91dERpY3RQYXRoIFxuICovXG5mdW5jdGlvbiBpbnNwZWN0RGVtb3Moc2VudGVuY2UsIG1hc2tJbmQ6IG51bWJlciwgbW9kZWxOYW1lOiBzdHJpbmcsIGNvcnB1c05hbWU6IHN0cmluZywgb3V0RGljdFBhdGgpIHtcbiAgICBjb25zdCBhcGkgPSBuZXcgQVBJKClcblxuICAgIGNvbnN0IGNvbnRlbnRIYXNoID0ge31cblxuICAgIC8vIEdldCB0aGUgYmFzZSByZXR1cm4gZm9yIGFsbCBwYWdlIGluaXRpYWxpemF0aW9uc1xuICAgIF8ucmFuZ2UoMSkuZm9yRWFjaChMID0+IHtcbiAgICAgICAgYXBpLmdldE1ldGFBdHRlbnRpb25zKG1vZGVsTmFtZSwgc2VudGVuY2UsIEwsIFwiXCIpLnRoZW4ocjAgPT4ge1xuICAgICAgICAgICAgY29uc3QgdG9rQ2Fwc3VsZSA9IG5ldyBUb2tlbldyYXBwZXIocjAucGF5bG9hZCk7XG5cbiAgICAgICAgICAgIC8vIFVubWFza2VkIHJlc3BvbnNlOlxuICAgICAgICAgICAgYXBpLnVwZGF0ZU1hc2tlZEF0dGVudGlvbnMobW9kZWxOYW1lLCB0b2tDYXBzdWxlLmEsIHNlbnRlbmNlLCBMLCBlbXB0eVRva2VuRGlzcGxheSkudGhlbihyMSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gTWFza2VkIHdvcmQgYW5kIHNlYXJjaGluZyByZXNwb25zZXM6XG4gICAgICAgICAgICAgICAgdG9rQ2Fwc3VsZS5hLm1hc2sobWFza0luZClcbiAgICAgICAgICAgICAgICBhcGkudXBkYXRlTWFza2VkQXR0ZW50aW9ucyhtb2RlbE5hbWUsIHRva0NhcHN1bGUuYSwgc2VudGVuY2UsIEwsIGVtcHR5VG9rZW5EaXNwbGF5KS50aGVuKHIyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2cocjIpO1xuICAgICAgICAgICAgICAgICAgICAvLyBHZXQgc2VhcmNoIHJlc3VsdHMgYnkgZW1iZWRkaW5nXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtYmVkZGluZyA9IHIyWydhYSddWydsZWZ0J11bbWFza0luZF0uZW1iZWRkaW5nc1xuICAgICAgICAgICAgICAgICAgICBhcGkuZ2V0TmVhcmVzdEVtYmVkZGluZ3MobW9kZWxOYW1lLCBjb3JwdXNOYW1lLCBlbWJlZGRpbmcsIEwsIF8ucmFuZ2UoMTIpLCA1MCwgY29udGVudEhhc2gpLnRoZW4oeCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gR2V0IHNlYXJjaCByZXN1bHRzIGJ5IGNvbnRleHRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHIyWydhYSddWydsZWZ0J11bbWFza0luZF0uY29udGV4dHNcbiAgICAgICAgICAgICAgICAgICAgYXBpLmdldE5lYXJlc3RDb250ZXh0cyhtb2RlbE5hbWUsIGNvcnB1c05hbWUsIGNvbnRleHQsIEwsIF8ucmFuZ2UoMTIpLCA1MCkudGhlbih4ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9KVxufVxuXG5mdW5jdGlvbiByZXBsVGVzdCgpIHtcbiAgICAvLyBUZXN0ZXIudGVzdEF0dFdyYXBwZXJDb25zdHJ1Y3RvcigpXG4gICAgLy8gVGVzdGVyLnRlc3RVcGRhdGVNYXNrZWRBdHRlbnRpb24oKVxuICAgIC8vIFRlc3Rlci50ZXN0TmpBcmF5KCk7XG4gICAgLy8gVGVzdGVyLnRlc3RSYW5kb21BcnJheUNyZWF0aW9uKCk7XG4gICAgLy8gVGVzdGVyLnRlc3RGYWlzc1dyYXBwZXIoKTtcbiAgICAvLyBUZXN0ZXIudGVzdEQzT3JkaW5hbCgpO1xuICAgIC8vIFRlc3Rlci50ZXN0RmFpc3NTZWFyY2hSZXN1bHRzSGlzdCgpO1xuICAgIC8vIFRlc3Rlci50ZXN0UmVhZGluZ0pTT04oKTtcbn1cblxud2luZG93Lm9ubG9hZCA9ICgpID0+IHtcbiAgICBkb015U3ZnKCk7XG4gICAgLy8gcmVwbFRlc3QoKTtcbiAgICAvLyBjcmVhdGVEZW1vcyhcIkNoaWNrZW4gdGFzdGVzIGFic29sdXRlbHkgZGVsaWNpb3VzIGlmIHlvdSBrbm93IHdoYXQgeW91J3JlIGRvaW5nXCIsIDQsIFwiXCIpXG4gICAgY29uc29sZS5sb2coXCJEb25lIGxvYWRpbmcgd2luZG93XCIpO1xufVxuIiwiaW1wb3J0ICogYXMgdHAgZnJvbSBcIi4vZXRjL3R5cGVzXCJcbmltcG9ydCAqIGFzIHhfIGZyb20gXCIuL2V0Yy9fVG9vbHNcIlxuaW1wb3J0ICogYXMgXyBmcm9tIFwibG9kYXNoXCJcbmltcG9ydCAqIGFzIFIgZnJvbSAncmFtZGEnXG5pbXBvcnQgeyBVUkxIYW5kbGVyIH0gZnJvbSBcIi4vZXRjL1VSTEhhbmRsZXJcIjtcblxuY29uc3QgZmFsc2V5ID0gdmFsID0+IChuZXcgU2V0KFsnZmFsc2UnLCAwLCBcIm5vXCIsIGZhbHNlLCBudWxsLCBcIlwiXSkpLmhhcyh2YWwpXG5jb25zdCB0cnV0aHkgPSB2YWwgPT4gIWZhbHNleSh2YWwpXG5jb25zdCB0b051bWJlciA9IHggPT4gK3g7XG5cblxudHlwZSBJbnNwZWN0b3JPcHRpb25zID0gXCJjb250ZXh0XCIgfCBcImVtYmVkZGluZ3NcIiB8IG51bGxcblxuLy8gTXVzdCBiZSBvcHRpb25hbCBwYXJhbXMgZm9yIGluaXRpYWxpemF0aW9uc1xuaW50ZXJmYWNlIFVSTFBhcmFtZXRlcnMge1xuICAgIHNlbnRlbmNlPzogc3RyaW5nXG4gICAgbW9kZWw/OiBzdHJpbmdcbiAgICBtb2RlbEtpbmQ/OiBzdHJpbmdcbiAgICBjb3JwdXM/OiBzdHJpbmdcbiAgICBsYXllcj86IG51bWJlclxuICAgIGhlYWRzPzogbnVtYmVyW11cbiAgICB0aHJlc2hvbGQ/OiBudW1iZXJcbiAgICB0b2tlbkluZD86IG51bWJlciB8ICdudWxsJ1xuICAgIHRva2VuU2lkZT86IHRwLlNpZGVPcHRpb25zXG4gICAgbWV0YU1hdGNoPzogdHAuU2ltcGxlTWV0YSB8IG51bGxcbiAgICBtZXRhTWF4PzogdHAuU2ltcGxlTWV0YSB8IG51bGxcbiAgICBkaXNwbGF5SW5zcGVjdG9yPzogSW5zcGVjdG9yT3B0aW9uc1xuICAgIG9mZnNldElkeHM/OiBudW1iZXJbXVxuICAgIG1hc2tJbmRzPzogbnVtYmVyW11cbiAgICBoaWRlQ2xzU2VwPzogYm9vbGVhblxufVxuXG5leHBvcnQgY2xhc3MgVUlDb25maWcge1xuXG4gICAgcHJpdmF0ZSBfY29uZjogVVJMUGFyYW1ldGVycyA9IHt9XG4gICAgcHJpdmF0ZSBfaGVhZFNldDogU2V0PG51bWJlcj47XG4gICAgYXR0VHlwZTogdHAuU2VudGVuY2VPcHRpb25zO1xuICAgIF9uSGVhZHM6IG51bWJlciB8IG51bGw7XG4gICAgX25MYXllcnM6IG51bWJlciB8IG51bGw7XG4gICAgcHJpdmF0ZSBfdG9rZW46IHRwLlRva2VuRXZlbnQ7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5fbkhlYWRzID0gMTI7IC8vIEhvdyBkbyBJIGF1dG9tYXRlIHRoaXM/XG4gICAgICAgIHRoaXMuX25MYXllcnMgPSBudWxsO1xuICAgICAgICB0aGlzLmF0dFR5cGUgPSAnYWEnOyAvLyBEb24ndCBhbGxvdyB0aGlzIHRvIGJlIG1vZGlmaWVkIGJ5IHRoZSB1c2VyLlxuICAgICAgICB0aGlzLmZyb21VUkwoKVxuICAgICAgICB0aGlzLnRvVVJMKGZhbHNlKVxuICAgIH1cblxuXG4gICAgZnJvbVVSTCgpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gVVJMSGFuZGxlci5wYXJhbWV0ZXJzXG5cbiAgICAgICAgdGhpcy5fY29uZiA9IHtcbiAgICAgICAgICAgIG1vZGVsOiBwYXJhbXNbJ21vZGVsJ10gfHwgJ2JlcnQtYmFzZS1jYXNlZCcsXG4gICAgICAgICAgICBtb2RlbEtpbmQ6IHBhcmFtc1snbW9kZWxLaW5kJ10gfHwgdHAuTW9kZWxLaW5kLkJpZGlyZWN0aW9uYWwsXG4gICAgICAgICAgICBzZW50ZW5jZTogcGFyYW1zWydzZW50ZW5jZSddIHx8IFwiVGhlIGdpcmwgcmFuIHRvIGEgbG9jYWwgcHViIHRvIGVzY2FwZSB0aGUgZGluIG9mIGhlciBjaXR5LlwiLFxuICAgICAgICAgICAgY29ycHVzOiBwYXJhbXNbJ2NvcnB1cyddIHx8ICd3b3onLFxuICAgICAgICAgICAgbGF5ZXI6IHBhcmFtc1snbGF5ZXInXSB8fCAxLFxuICAgICAgICAgICAgaGVhZHM6IHRoaXMuX2luaXRIZWFkcyhwYXJhbXNbJ2hlYWRzJ10pLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBwYXJhbXNbJ3RocmVzaG9sZCddIHx8IDAuNyxcbiAgICAgICAgICAgIHRva2VuSW5kOiBwYXJhbXNbJ3Rva2VuSW5kJ10gfHwgbnVsbCxcbiAgICAgICAgICAgIHRva2VuU2lkZTogcGFyYW1zWyd0b2tlblNpZGUnXSB8fCBudWxsLFxuICAgICAgICAgICAgbWFza0luZHM6IHBhcmFtc1snbWFza0luZHMnXSB8fCBbOV0sXG4gICAgICAgICAgICBtZXRhTWF0Y2g6IHBhcmFtc1snbWV0YU1hdGNoJ10gfHwgXCJwb3NcIixcbiAgICAgICAgICAgIG1ldGFNYXg6IHBhcmFtc1snbWV0YU1heCddIHx8IFwicG9zXCIsXG4gICAgICAgICAgICBkaXNwbGF5SW5zcGVjdG9yOiBwYXJhbXNbJ2Rpc3BsYXlJbnNwZWN0b3InXSB8fCBudWxsLFxuICAgICAgICAgICAgb2Zmc2V0SWR4czogdGhpcy5faW5pdE9mZnNldElkeHMocGFyYW1zWydvZmZzZXRJZHhzJ10pLFxuICAgICAgICAgICAgaGlkZUNsc1NlcDogdHJ1dGh5KHBhcmFtc1snaGlkZUNsc1NlcCddKSB8fCB0cnVlLFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdG9rZW4gPSB7IHNpZGU6IHRoaXMuX2NvbmYudG9rZW5TaWRlLCBpbmQ6IHRoaXMuX2NvbmYudG9rZW5JbmQgfVxuXG4gICAgfVxuXG4gICAgdG9VUkwodXBkYXRlSGlzdG9yeSA9IGZhbHNlKSB7XG4gICAgICAgIFVSTEhhbmRsZXIudXBkYXRlVXJsKHRoaXMuX2NvbmYsIHVwZGF0ZUhpc3RvcnkpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5pdE9mZnNldElkeHModjogKHN0cmluZyB8IG51bWJlcilbXSB8IG51bGwpIHtcbiAgICAgICAgaWYgKHYgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIFstMSwgMCwgMV1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG51bWJlckFyciA9IFIubWFwKHRvTnVtYmVyLCB2KTtcbiAgICAgICAgICAgIHJldHVybiBudW1iZXJBcnI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0SGVhZHModjogbnVtYmVyW10gfCBudWxsKSB7XG4gICAgICAgIGlmICh2ID09IG51bGwgfHwgdi5sZW5ndGggPCAxKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdEFsbEhlYWRzKClcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuaGVhZFNldChuZXcgU2V0KHYpKS5fY29uZi5oZWFkcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5oZWFkcygpXG4gICAgfVxuXG4gICAgbkhlYWRzKCk6IG51bWJlclxuICAgIG5IZWFkcyh2YWw6IG51bWJlcik6IHRoaXNcbiAgICBuSGVhZHModmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9uSGVhZHNcbiAgICAgICAgdGhpcy5fbkhlYWRzID0gdmFsXG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgbkxheWVycygpOiBudW1iZXJcbiAgICBuTGF5ZXJzKHZhbDogbnVtYmVyKTogdGhpc1xuICAgIG5MYXllcnModmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9uTGF5ZXJzXG4gICAgICAgIHRoaXMuX25MYXllcnMgPSB2YWxcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICB0b2dnbGVTZWxlY3RBbGxIZWFkcygpIHtcbiAgICAgICAgaWYgKHRoaXMuaGVhZHMoKS5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RBbGxIZWFkcygpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdE5vSGVhZHMoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2VsZWN0QWxsSGVhZHMoKSB7XG4gICAgICAgIHRoaXMuaGVhZFNldChuZXcgU2V0KF8ucmFuZ2UoMCwgdGhpcy5fbkhlYWRzKSkpXG4gICAgfVxuXG4gICAgc2VsZWN0Tm9IZWFkcygpIHtcbiAgICAgICAgdGhpcy5oZWFkU2V0KG5ldyBTZXQoW10pKVxuICAgIH1cblxuICAgIHRvZ2dsZUhlYWQoaGVhZDogbnVtYmVyKTogdHAuVG9nZ2xlZCB7XG4gICAgICAgIGxldCBvdXQ7XG4gICAgICAgIGlmICh0aGlzLmhlYWRTZXQoKS5oYXMoaGVhZCkpIHtcbiAgICAgICAgICAgIHRoaXMuaGVhZFNldCgpLmRlbGV0ZShoZWFkKTtcbiAgICAgICAgICAgIG91dCA9IHRwLlRvZ2dsZWQuUkVNT1ZFRFxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWFkU2V0KCkuYWRkKGhlYWQpO1xuICAgICAgICAgICAgb3V0ID0gdHAuVG9nZ2xlZC5BRERFRFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHRocm91Z2ggc2V0dGVyIGZ1bmN0aW9uIHRvIGVuc3VyZSB1cmwgaXMgdXBkYXRlZFxuICAgICAgICB0aGlzLmhlYWRTZXQodGhpcy5oZWFkU2V0KCkpOyAvLyBJIGhhdGUgbXV0YWJsZSBkYXRhc3RydWN0dXJlcy4uLiBUaGlzIGlzIGNvbmZ1c2luZy5cblxuICAgICAgICByZXR1cm4gb3V0XG4gICAgfVxuXG4gICAgdG9nZ2xlVG9rZW4oZTogdHAuVG9rZW5FdmVudCk6IHRoaXMge1xuICAgICAgICBjb25zdCBwaWNrZXIgPSBSLnBpY2soWydpbmQnLCAnc2lkZSddKVxuICAgICAgICBjb25zdCBjb21wYXJlRXZlbnQgPSBwaWNrZXIoZSlcbiAgICAgICAgY29uc3QgY29tcGFyZVRva2VuID0gcGlja2VyKHRoaXMudG9rZW4oKSlcblxuICAgICAgICBpZiAoUi5lcXVhbHMoY29tcGFyZVRva2VuLCBjb21wYXJlRXZlbnQpKSB7XG4gICAgICAgICAgICB0aGlzLnJtVG9rZW4oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudG9rZW4oZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdG9rZW4oKTogdHAuVG9rZW5FdmVudDtcbiAgICB0b2tlbih2YWw6IHRwLlRva2VuRXZlbnQpOiB0aGlzO1xuICAgIHRva2VuKHZhbD86IHRwLlRva2VuRXZlbnQpIHtcbiAgICAgICAgaWYgKHZhbCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Rva2VuXG5cbiAgICAgICAgdGhpcy5fdG9rZW4gPSB2YWw7XG4gICAgICAgIHRoaXMuX2NvbmYudG9rZW5JbmQgPSB2YWwuaW5kO1xuICAgICAgICB0aGlzLl9jb25mLnRva2VuU2lkZSA9IHZhbC5zaWRlO1xuICAgICAgICB0aGlzLnRvVVJMKCk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBoYXNUb2tlbigpIHtcbiAgICAgICAgY29uc3QgY29uZiA9IHRoaXMuX2NvbmZcbiAgICAgICAgY29uc3QgYWN0dWFsbHlOdWxsID0gKChjb25mLnRva2VuSW5kID09IG51bGwpICYmIChjb25mLnRva2VuU2lkZSA9PSBudWxsKSlcbiAgICAgICAgY29uc3Qgc3RyTnVsbCA9IChjb25mLnRva2VuSW5kID09IFwibnVsbFwiKVxuICAgICAgICByZXR1cm4gKCFhY3R1YWxseU51bGwpICYmICghc3RyTnVsbClcbiAgICB9XG5cbiAgICBybVRva2VuKCkge1xuICAgICAgICB0aGlzLnRva2VuKHsgaW5kOiBudWxsLCBzaWRlOiBudWxsIH0pO1xuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHNlbnRlbmNlKCk6IHN0cmluZztcbiAgICBzZW50ZW5jZSh2YWw6IHN0cmluZyk6IHRoaXM7XG4gICAgc2VudGVuY2UodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29uZi5zZW50ZW5jZVxuXG4gICAgICAgIHRoaXMuX2NvbmYuc2VudGVuY2UgPSB2YWxcbiAgICAgICAgdGhpcy50b1VSTCh0cnVlKVxuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIHRocmVzaG9sZCgpOiBudW1iZXI7XG4gICAgdGhyZXNob2xkKHZhbDogbnVtYmVyKTogdGhpcztcbiAgICB0aHJlc2hvbGQodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLnRocmVzaG9sZDtcblxuICAgICAgICB0aGlzLl9jb25mLnRocmVzaG9sZCA9IHZhbDtcbiAgICAgICAgdGhpcy50b1VSTCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBoZWFkcygpOiBudW1iZXJbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb25mLmhlYWRzXG4gICAgfVxuXG4gICAgbGF5ZXIoKTogbnVtYmVyXG4gICAgbGF5ZXIodmFsOiBudW1iZXIpOiB0aGlzXG4gICAgbGF5ZXIodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29uZi5sYXllclxuXG4gICAgICAgIHRoaXMuX2NvbmYubGF5ZXIgPSB2YWw7XG4gICAgICAgIHRoaXMudG9VUkwoKTtcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBoZWFkU2V0KCk6IFNldDxudW1iZXI+O1xuICAgIGhlYWRTZXQodmFsOiBTZXQ8bnVtYmVyPik6IHRoaXM7XG4gICAgaGVhZFNldCh2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2hlYWRTZXQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9oZWFkU2V0ID0gdmFsO1xuICAgICAgICB0aGlzLl9jb25mLmhlYWRzID0geF8uc2V0MlNvcnRlZEFycmF5KHRoaXMuX2hlYWRTZXQpXG4gICAgICAgIHRoaXMudG9VUkwoKTtcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG5cbiAgICBtZXRhTWF0Y2goKTogdHAuU2ltcGxlTWV0YTtcbiAgICBtZXRhTWF0Y2godmFsOiB0cC5TaW1wbGVNZXRhKTogdGhpcztcbiAgICBtZXRhTWF0Y2godmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLm1ldGFNYXg7XG5cbiAgICAgICAgdGhpcy5fY29uZi5tZXRhTWF4ID0gdmFsO1xuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIG1ldGFNYXgoKTogdHAuU2ltcGxlTWV0YTtcbiAgICBtZXRhTWF4KHZhbDogdHAuU2ltcGxlTWV0YSk6IHRoaXM7XG4gICAgbWV0YU1heCh2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkgcmV0dXJuIHRoaXMuX2NvbmYubWV0YU1hdGNoO1xuXG4gICAgICAgIHRoaXMuX2NvbmYubWV0YU1hdGNoID0gdmFsO1xuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIG1hc2tJbmRzKCk6IG51bWJlcltdO1xuICAgIG1hc2tJbmRzKHZhbDogbnVtYmVyW10pOiB0aGlzO1xuICAgIG1hc2tJbmRzKHZhbD8pIHtcbiAgICAgICAgaWYgKHZhbCA9PSBudWxsKSByZXR1cm4gdGhpcy5fY29uZi5tYXNrSW5kcztcblxuICAgICAgICB0aGlzLl9jb25mLm1hc2tJbmRzID0gdmFsO1xuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGRpc3BsYXlJbnNwZWN0b3IoKTogSW5zcGVjdG9yT3B0aW9ucztcbiAgICBkaXNwbGF5SW5zcGVjdG9yKHZhbDogSW5zcGVjdG9yT3B0aW9ucyk6IHRoaXM7XG4gICAgZGlzcGxheUluc3BlY3Rvcih2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkgcmV0dXJuIHRoaXMuX2NvbmYuZGlzcGxheUluc3BlY3RvcjtcblxuICAgICAgICB0aGlzLl9jb25mLmRpc3BsYXlJbnNwZWN0b3IgPSB2YWw7XG4gICAgICAgIHRoaXMudG9VUkwoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgb2Zmc2V0SWR4cygpOiBudW1iZXJbXTtcbiAgICBvZmZzZXRJZHhzKHZhbDogbnVtYmVyW10pOiB0aGlzO1xuICAgIG9mZnNldElkeHModmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLm9mZnNldElkeHM7XG5cbiAgICAgICAgLy8gY29udmVydCB0byBudW1iZXJzXG5cbiAgICAgICAgdGhpcy5fY29uZi5vZmZzZXRJZHhzID0gUi5tYXAodG9OdW1iZXIsIHZhbCk7XG4gICAgICAgIHRoaXMudG9VUkwoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaGlkZUNsc1NlcCgpOiBib29sZWFuO1xuICAgIGhpZGVDbHNTZXAodmFsOiBib29sZWFuKTogdGhpcztcbiAgICBoaWRlQ2xzU2VwKHZhbD8pIHtcbiAgICAgICAgaWYgKHZhbCA9PSBudWxsKSByZXR1cm4gdGhpcy5fY29uZi5oaWRlQ2xzU2VwO1xuXG4gICAgICAgIHRoaXMuX2NvbmYuaGlkZUNsc1NlcCA9IHRydXRoeSh2YWwpO1xuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIG1vZGVsKCk6IHN0cmluZztcbiAgICBtb2RlbCh2YWw6IHN0cmluZyk6IHRoaXM7XG4gICAgbW9kZWwodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLm1vZGVsXG4gICAgICAgIHRoaXMuX2NvbmYubW9kZWwgPSB2YWxcbiAgICAgICAgdGhpcy50b1VSTCgpO1xuICAgICAgICByZXR1cm4gdGhpc1xuICAgIH1cblxuICAgIG1vZGVsS2luZCgpOiBzdHJpbmc7XG4gICAgbW9kZWxLaW5kKHZhbDogc3RyaW5nKTogdGhpcztcbiAgICBtb2RlbEtpbmQodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLm1vZGVsS2luZFxuICAgICAgICB0aGlzLl9jb25mLm1vZGVsS2luZCA9IHZhbFxuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBvZmZzZXQgbmVlZGVkIGZvciB0aGUgbW9kZWxLaW5kIGluIHRoZSBjb25maWd1cmF0aW9uXG4gICAgICovXG4gICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLm1vZGVsS2luZCgpKSB7XG4gICAgICAgICAgICBjYXNlIHRwLk1vZGVsS2luZC5CaWRpcmVjdGlvbmFsOiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgdHAuTW9kZWxLaW5kLkF1dG9yZWdyZXNzaXZlOiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IHNob3dOZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5tb2RlbEtpbmQoKSA9PSB0cC5Nb2RlbEtpbmQuQXV0b3JlZ3Jlc3NpdmUgPyB0cnVlIDogZmFsc2VcbiAgICB9XG5cbiAgICBnZXQgbWF0Y2hIaXN0b2dyYW1EZXNjcmlwdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZWxLaW5kKCkgPT0gdHAuTW9kZWxLaW5kLkF1dG9yZWdyZXNzaXZlID8gXCJOZXh0XCIgOiBcIk1hdGNoZWRcIlxuICAgIH1cblxuICAgIGNvcnB1cygpOiBzdHJpbmc7XG4gICAgY29ycHVzKHZhbDogc3RyaW5nKTogdGhpcztcbiAgICBjb3JwdXModmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHJldHVybiB0aGlzLl9jb25mLmNvcnB1c1xuICAgICAgICB0aGlzLl9jb25mLmNvcnB1cyA9IHZhbFxuICAgICAgICB0aGlzLnRvVVJMKCk7XG4gICAgICAgIHJldHVybiB0aGlzXG4gICAgfVxufVxuIiwiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgJ2QzLXNlbGVjdGlvbi1tdWx0aSdcbmltcG9ydCB7IEQzU2VsIH0gZnJvbSBcIi4uL2V0Yy9VdGlsXCI7XG5pbXBvcnQgeyBFZGdlLCBFZGdlRGF0YSB9IGZyb20gXCIuL0VkZ2VDb25uZWN0b3JcIlxuaW1wb3J0IHsgVkNvbXBvbmVudCB9IGZyb20gXCIuL1Zpc0NvbXBvbmVudFwiO1xuaW1wb3J0IHsgU2ltcGxlRXZlbnRIYW5kbGVyIH0gZnJvbSBcIi4uL2V0Yy9TaW1wbGVFdmVudEhhbmRsZXJcIjtcbmltcG9ydCAqIGFzIHRwIGZyb20gXCIuLi9ldGMvdHlwZXNcIlxuXG5leHBvcnQgdHlwZSBBdHRlbnRpb25EYXRhID0gbnVtYmVyW11bXVxuXG5leHBvcnQgY29uc3Qgc2NhbGVMaW5lYXJXaWR0aCA9IG9wYWNpdHkgPT4gNSAqIG9wYWNpdHleMC4zMztcblxuZXhwb3J0IGNsYXNzIEF0dGVudGlvbkdyYXBoIGV4dGVuZHMgVkNvbXBvbmVudDxBdHRlbnRpb25EYXRhPntcbiAgICBjc3NfbmFtZSA9ICcnO1xuICAgIF9jdXJyZW50OiB7fTtcblxuICAgIF9kYXRhOiBBdHRlbnRpb25EYXRhOyAvLyBUaGUgcGFzc2VkIGRhdGFcbiAgICBlZGdlRGF0YTogRWRnZURhdGE7IC8vIEEgd3JhcHBlciBhcm91bmQgX2RhdGEuIFVzZXIgc2hvdWxkIG5vdCBtaW5kXG4gICAgcGxvdERhdGE6IEVkZ2VbXTsgLy8gTmVlZGVkIGZvciBwbG90dGluZ1xuXG4gICAgLyoqIENPTVBPTkVOVFNcbiAgICAgKiBFeHBvc2UgdGhlIGNvbXBvbmVudHMgYmVsb25naW5nIHRvIHRoZSBjbGFzcyBhcyBwcm9wZXJ0aWVzIG9mIHRoZSBjbGFzcy4gXG4gICAgICogVGhpcyBpcyB1c2VmdWwgdG8gY3JlYXRlIG1ldGhvZHMgdGhhdCBzcGVjaWZpY2FsbHkgbW9kaWZ5IGEgc2luZ2xlIHBhcnQgb3IgY29tcG9uZW50IHdpdGhvdXQgaGF2aW5nIHRvIHJlc2VsZWN0IGl0LiBcbiAgICAgKiBNYWtlcyBmb3IgbW9yZSByZXNwb25zaXZlIGFwcGxpY2F0aW9uc1xuICAgICAqICovXG4gICAgc3ZnOiBEM1NlbDtcbiAgICBncmFwaDogRDNTZWw7XG5cbiAgICAvLyBUaGUgYmVsb3cgY29tcG9uZW50cyByZXF1aXJlIGRhdGFcbiAgICBwYXRoczogRDNTZWw7XG4gICAgb3BhY2l0eVNjYWxlczogZDMuU2NhbGVMaW5lYXI8YW55LCBhbnk+W107XG4gICAgbGlua0dlbjogZDMuTGluazxhbnksIGFueSwgYW55PlxuXG4gICAgLy8gT1BUSU9OUyBXSVRIIERFRkFVTFRTXG4gICAgX3RocmVzaG9sZCA9IDAuNzsgLy8gQWNjdW11bGF0aW9uIHRocmVzaG9sZC4gQmV0d2VlbiAwLTFcbiAgICBub3JtQnk6IHRwLk5vcm1CeVxuXG4gICAgc3RhdGljIGV2ZW50cyA9IHt9IC8vIE5vIGV2ZW50cyBuZWVkZWQgZm9yIHRoaXMgb25lXG5cbiAgICBvcHRpb25zID0ge1xuICAgICAgICBib3hoZWlnaHQ6IDI2LCAvLyBUaGUgaGVpZ2h0IG9mIHRoZSBkaXYgYm94ZXMgYXJvdW5kIHRoZSBTVkcgZWxlbWVudFxuICAgICAgICBoZWlnaHQ6IDUwMCxcbiAgICAgICAgd2lkdGg6IDIwMCxcbiAgICAgICAgb2Zmc2V0OiAwLCAvLyBTaG91bGQgSSBvZmZzZXQgdGhlIGxlZnQgc2lkZSBieSAxIG9yIG5vdD9cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihkM1BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86IFNpbXBsZUV2ZW50SGFuZGxlciwgb3B0aW9uczoge30gPSB7fSkge1xuICAgICAgICBzdXBlcihkM1BhcmVudCwgZXZlbnRIYW5kbGVyKVxuICAgICAgICB0aGlzLnN1cGVySW5pdFNWRyhvcHRpb25zKVxuICAgICAgICB0aGlzLl9pbml0KClcbiAgICB9XG5cbiAgICBfaW5pdCgpIHtcbiAgICAgICAgdGhpcy5zdmcgPSB0aGlzLnBhcmVudDtcbiAgICAgICAgdGhpcy5ncmFwaCA9IHRoaXMuc3ZnLnNlbGVjdEFsbChgLmF0bi1jdXJ2ZWApO1xuICAgICAgICB0aGlzLmxpbmtHZW4gPSBkMy5saW5rSG9yaXpvbnRhbCgpXG4gICAgICAgICAgICAueChkID0+IGRbMF0pXG4gICAgICAgICAgICAueShkID0+IGRbMV0pO1xuICAgIH1cblxuICAgIC8vIERlZmluZSB3aGV0aGVyIHRvIHVzZSB0aGUgJ2onIG9yICdpJyBhdHRyaWJ1dGUgdG8gY2FsY3VsYXRlIG9wYWNpdGllc1xuICAgIHByaXZhdGUgc2NhbGVJZHgoKTogXCJpXCIgfCBcImpcIiB7XG4gICAgICAgIHN3aXRjaCAodGhpcy5ub3JtQnkpIHtcbiAgICAgICAgICAgIGNhc2UgdHAuTm9ybUJ5LkNvbDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2onXG4gICAgICAgICAgICBjYXNlIHRwLk5vcm1CeS5Sb3c6XG4gICAgICAgICAgICAgICAgcmV0dXJuICdpJ1xuICAgICAgICAgICAgY2FzZSB0cC5Ob3JtQnkuQWxsOlxuICAgICAgICAgICAgICAgIHJldHVybiAnaSdcblxuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgY29ubmVjdGlvbnMgYmV0d2VlbiBsb2NhdGlvbnMgb2YgdGhlIFNWRyB1c2luZyBEMydzIGxpbmtHZW5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNyZWF0ZUNvbm5lY3Rpb25zKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgY29uc3Qgb3AgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICh0aGlzLnBhdGhzKSB7XG4gICAgICAgICAgICB0aGlzLnBhdGhzLmF0dHJzKHtcbiAgICAgICAgICAgICAgICAnZCc6IChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGE6IHsgc291cmNlOiBbbnVtYmVyLCBudW1iZXJdLCB0YXJnZXQ6IFtudW1iZXIsIG51bWJlcl0gfSA9XG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZTogWzAsIG9wLmJveGhlaWdodCAqIChkLmkgKyAwLjUgKyBvcC5vZmZzZXQpXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldDogW29wLndpZHRoLCBvcC5ib3hoZWlnaHQgKiAoZC5qICsgMC41KV0gLy8gKyAyIGFsbG93cyBzbWFsbCBvZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGlua0dlbihkYXRhKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICdjbGFzcyc6ICdhdG4tY3VydmUnXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5hdHRyKFwic3JjLWlkeFwiLCAoZCwgaSkgPT4gZC5pKVxuICAgICAgICAgICAgICAgIC5hdHRyKFwidGFyZ2V0LWlkeFwiLCAoZCwgaSkgPT4gZC5qKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoYW5nZSB0aGUgaGVpZ2h0IG9mIHRoZSBTVkdcbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZUhlaWdodCgpIHtcbiAgICAgICAgY29uc3Qgb3AgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGlmICh0aGlzLnN2ZyAhPSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnN2Zy5hdHRyKFwiaGVpZ2h0XCIsIHRoaXMub3B0aW9ucy5oZWlnaHQgKyAob3Aub2Zmc2V0ICogdGhpcy5vcHRpb25zLmJveGhlaWdodCkpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hhbmdlIHRoZSB3aWR0aCBvZiB0aGUgU1ZHXG4gICAgICovXG4gICAgcHJpdmF0ZSB1cGRhdGVXaWR0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuc3ZnICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuc3ZnLmF0dHIoXCJ3aWR0aFwiLCB0aGlzLm9wdGlvbnMud2lkdGgpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hhbmdlIHRoZSBPcGFjaXR5IG9mIHRoZSBsaW5lcyBhY2NvcmRpbmcgdG8gdGhlIHZhbHVlIG9mIHRoZSBkYXRhXG4gICAgICovXG4gICAgcHJpdmF0ZSB1cGRhdGVPcGFjaXR5KCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgaWYgKHRoaXMucGF0aHMgIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gcGF0aHMudHJhbnNpdGlvbigpLmR1cmF0aW9uKDUwMCkuYXR0cignb3BhY2l0eScsIChkKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBhdGhzLmF0dHIoJ29wYWNpdHknLCAoZCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbCA9IHRoaXMub3BhY2l0eVNjYWxlc1tkW3NlbGYuc2NhbGVJZHgoKV1dKGQudik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB0aGlzLnBhdGhzLmF0dHIoJ3N0cm9rZS13aWR0aCcsIChkKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsID0gdGhpcy5vcGFjaXR5U2NhbGVzW2Rbc2VsZi5zY2FsZUlkeCgpXV0oZC52KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NhbGVMaW5lYXJXaWR0aCh2YWwpIC8vNSAqIHZhbF4wLjMzO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXJlbmRlciB0aGUgZ3JhcGggaW4gdGhlIGV2ZW50IHRoYXQgdGhlIGRhdGEgY2hhbmdlc1xuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlRGF0YSgpIHtcbiAgICAgICAgaWYgKHRoaXMuZ3JhcGggIT0gbnVsbCkge1xuICAgICAgICAgICAgZDMuc2VsZWN0QWxsKFwiLmF0bi1jdXJ2ZVwiKS5yZW1vdmUoKTtcblxuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMucGxvdERhdGFcblxuICAgICAgICAgICAgdGhpcy5wYXRocyA9IHRoaXMuZ3JhcGhcbiAgICAgICAgICAgICAgICAuZGF0YShkYXRhKVxuICAgICAgICAgICAgICAgIC5qb2luKCdwYXRoJyk7XG5cbiAgICAgICAgICAgIHRoaXMuY3JlYXRlQ29ubmVjdGlvbnMoKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlT3BhY2l0eSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNjYWxlIHRoZSBvcGFjaXR5IGFjY29yZGluZyB0byB0aGUgdmFsdWVzIG9mIHRoZSBkYXRhLCBmcm9tIDAgdG8gbWF4IG9mIGNvbnRhaW5lZCBkYXRhXG4gICAgICogTm9ybWFsaXplIGJ5IGVhY2ggc291cmNlIHRhcmdldCwgb3IgYWNyb3NzIHRoZSB3aG9sZVxuICAgICAqL1xuICAgIHByaXZhdGUgY3JlYXRlU2NhbGVzID0gKCkgPT4ge1xuICAgICAgICB0aGlzLm9wYWNpdHlTY2FsZXMgPSBbXTtcbiAgICAgICAgbGV0IGFyciA9IFtdXG5cbiAgICAgICAgLy8gR3JvdXAgbm9ybWFsaXphdGlvblxuICAgICAgICBzd2l0Y2ggKHRoaXMubm9ybUJ5KXtcbiAgICAgICAgICAgIGNhc2UgdHAuTm9ybUJ5LlJvdzpcbiAgICAgICAgICAgICAgICBhcnIgPSB0aGlzLmVkZ2VEYXRhLmV4dGVudCgxKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9wYWNpdHlTY2FsZXMgPSBbXTtcbiAgICAgICAgICAgICAgICBhcnIuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAodGhpcy5vcGFjaXR5U2NhbGVzIGFzIGQzLlNjYWxlTGluZWFyPGFueSwgYW55PltdKS5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgZDMuc2NhbGVMaW5lYXIoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kb21haW4oWzAsIHZbMV1dKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yYW5nZShbMCwgMC45XSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRwLk5vcm1CeS5Db2w6XG4gICAgICAgICAgICAgICAgYXJyID0gdGhpcy5lZGdlRGF0YS5leHRlbnQoMCk7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGFjaXR5U2NhbGVzID0gW107XG4gICAgICAgICAgICAgICAgYXJyLmZvckVhY2goKHYsIGkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMub3BhY2l0eVNjYWxlcyBhcyBkMy5TY2FsZUxpbmVhcjxhbnksIGFueT5bXSkucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAgIGQzLnNjYWxlTGluZWFyKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZG9tYWluKFswLCB2WzFdXSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmFuZ2UoWzAsIDAuOV0pXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0cC5Ob3JtQnkuQWxsOlxuICAgICAgICAgICAgICAgIGNvbnN0IG1heEluID0gZDMubWF4KHRoaXMucGxvdERhdGEubWFwKChkKSA9PiBkLnYpKVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wYWNpdHlTY2FsZXMucHVzaChkMy5zY2FsZUxpbmVhcigpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZG9tYWluKFswLCBtYXhJbl0pXG4gICAgICAgICAgICAgICAgICAgICAgICAucmFuZ2UoWzAsIDFdKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIk5vciBub3JtaW5nIHNwZWNpZmllZFwiKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjY2VzcyAvIG1vZGlmeSB0aGUgZGF0YSBpbiBhIEQzIHN0eWxlIHdheS4gSWYgbW9kaWZpZWQsIHRoZSBjb21wb25lbnQgd2lsbCB1cGRhdGUganVzdCB0aGUgcGFydCB0aGF0IGlzIG5lZWRlZCB0byBiZSB1cGRhdGVkXG4gICAgICovXG4gICAgZGF0YSgpOiBBdHRlbnRpb25EYXRhXG4gICAgZGF0YSh2YWx1ZTogQXR0ZW50aW9uRGF0YSk6IHRoaXNcbiAgICBkYXRhKHZhbHVlPykge1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGE7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9kYXRhID0gdmFsdWU7XG4gICAgICAgIHRoaXMuZWRnZURhdGEgPSBuZXcgRWRnZURhdGEodmFsdWUpO1xuICAgICAgICB0aGlzLnBsb3REYXRhID0gdGhpcy5lZGdlRGF0YS5mb3JtYXQodGhpcy5fdGhyZXNob2xkKTtcbiAgICAgICAgdGhpcy5jcmVhdGVTY2FsZXMoKTtcbiAgICAgICAgdGhpcy51cGRhdGVEYXRhKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjY2VzcyAvIG1vZGlmeSB0aGUgaGVpZ2h0IGluIGEgRDMgc3R5bGUgd2F5LiBJZiBtb2RpZmllZCwgdGhlIGNvbXBvbmVudCB3aWxsIHVwZGF0ZSBqdXN0IHRoZSBwYXJ0IHRoYXQgaXMgbmVlZGVkIHRvIGJlIHVwZGF0ZWRcbiAgICAgKi9cbiAgICBoZWlnaHQoKTogbnVtYmVyXG4gICAgaGVpZ2h0KHZhbHVlOiBudW1iZXIpOiB0aGlzXG4gICAgaGVpZ2h0KHZhbHVlPykge1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5oZWlnaHRcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub3B0aW9ucy5oZWlnaHQgPSB2YWx1ZVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjY2VzcyAvIG1vZGlmeSB0aGUgd2lkdGggaW4gYSBEMyBzdHlsZSB3YXkuIElmIG1vZGlmaWVkLCB0aGUgY29tcG9uZW50IHdpbGwgdXBkYXRlIGp1c3QgdGhlIHBhcnQgdGhhdCBpcyBuZWVkZWQgdG8gYmUgdXBkYXRlZFxuICAgICAqL1xuICAgIHdpZHRoKCk6IG51bWJlclxuICAgIHdpZHRoKHZhbHVlOiBudW1iZXIpOiB0aGlzXG4gICAgd2lkdGgodmFsdWU/OiBudW1iZXIpOiB0aGlzIHwgbnVtYmVyIHtcbiAgICAgICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vcHRpb25zLndpZHRoID0gdmFsdWU7XG4gICAgICAgIHRoaXMudXBkYXRlV2lkdGgoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWNjZXNzIC8gbW9kaWZ5IHRoZSB0aHJlc2hvbGQgaW4gYSBEMyBzdHlsZSB3YXkuIElmIG1vZGlmaWVkLCB0aGUgY29tcG9uZW50IHdpbGwgdXBkYXRlIGp1c3QgdGhlIHBhcnQgdGhhdCBpcyBuZWVkZWQgdG8gYmUgdXBkYXRlZFxuICAgICAqL1xuICAgIHRocmVzaG9sZCgpOiBudW1iZXJcbiAgICB0aHJlc2hvbGQodmFsdWU6IG51bWJlcik6IHRoaXNcbiAgICB0aHJlc2hvbGQodmFsdWU/KSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGhyZXNob2xkO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fdGhyZXNob2xkID0gdmFsdWU7XG4gICAgICAgIHRoaXMucGxvdERhdGEgPSB0aGlzLmVkZ2VEYXRhLmZvcm1hdCh0aGlzLl90aHJlc2hvbGQpO1xuICAgICAgICB0aGlzLmNyZWF0ZVNjYWxlcygpO1xuICAgICAgICB0aGlzLnVwZGF0ZURhdGEoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgX3dyYW5nbGUoZGF0YTogQXR0ZW50aW9uRGF0YSkge1xuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBfcmVuZGVyKGRhdGE6IEF0dGVudGlvbkRhdGEpIHtcbiAgICAgICAgdGhpcy5zdmcuaHRtbCgnJylcbiAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgdGhpcy51cGRhdGVXaWR0aCgpO1xuXG4gICAgICAgIHRoaXMudXBkYXRlRGF0YSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59IiwiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgeyBWQ29tcG9uZW50IH0gZnJvbSBcIi4vVmlzQ29tcG9uZW50XCI7XG5pbXBvcnQgeyBTaW1wbGVFdmVudEhhbmRsZXIgfSBmcm9tIFwiLi4vZXRjL1NpbXBsZUV2ZW50SGFuZGxlclwiO1xuaW1wb3J0IHsgRDNTZWwgfSBmcm9tIFwiLi4vZXRjL1V0aWxcIjtcbmltcG9ydCB7IFNWRyB9IGZyb20gXCIuLi9ldGMvU1ZHcGx1c1wiXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICdAdGVuc29yZmxvdy90ZmpzJ1xuaW1wb3J0IHsgVGVuc29yM0QgfSBmcm9tIFwiQHRlbnNvcmZsb3cvdGZqc1wiO1xuXG4vLyBUaGUgYmVsb3cgdHdvIChpbnRlcmZhY2UgYW5kIGZ1bmN0aW9uKSBjYW4gYmVjb21lIGEgY2xhc3NcbmV4cG9ydCB0eXBlIEF0dGVudGlvbkhlYWRCb3hJID0ge1xuICAgIHJvd3M6IG51bWJlcltdW10sXG4gICAgbGFiZWxzOiBudW1iZXJbXSxcbiAgICBtYXg6IG51bWJlcixcbn1cblxuLyoqXG4gKiBGcm9tIGFuIGF0dGVudGlvbiBtYXRyaXggc2VsZWN0ZWQgYnkgbGF5ZXIsIHNob3cgYSBzdW1tYXJ5IG9mIHRoZSBhdHRlbnRpb25zIGJlbG9uZ2luZyB0byBlYWNoIGhlYWQuXG4gKiBcbiAqIEBwYXJhbSBoZWFkTWF0IFRoZSBtYXRyaXggcmVwcmVzZW50aW5nIGFsbCB0aGUgYXR0ZW50aW9ucyBieSBoZWFkIChsYXllciBhbHJlYWR5IHNlbGVjdGVkKSA8aGVhZCwgZnJvbSwgdG8+XG4gKiBAcGFyYW0gaGVhZExpc3QgVGhlIGhlYWRzIHRoYXQgYXJlIHNlbGVjdGVkXG4gKiBAcGFyYW0gc2lkZSBJcyB0aGlzIHRoZSByaWdodCBvciB0aGUgbGVmdCBkaXNwbGF5P1xuICogQHBhcmFtIHRva2VuSW5kIElmIG5vdCBudWxsLCBzZWxlY3QganVzdCB0aGUgaW5mb3JtYXRpb24gZnJvbSBhIHNpbmdsZSB0b2tlbiBhY3Jvc3MgaGVhZHNcbiAqIEByZXR1cm5zIEluZm9ybWF0aW9uIG5lZWRlZCB0byBsYWJlbCB0aGUgaGVhZGJveFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXR0ZW50aW9uSW5mbyhoZWFkTWF0OiBudW1iZXJbXVtdW10sIGhlYWRMaXN0OiBudW1iZXJbXSwgc2lkZTogXCJyaWdodFwiIHwgXCJsZWZ0XCIgPSBcImxlZnRcIiwgdG9rZW46IG51bGwgfCB7aW5kOiBudW1iZXIsIHNpZGU6IFwibGVmdFwiIHwgXCJyaWdodFwifT1udWxsKTogQXR0ZW50aW9uSGVhZEJveEkge1xuICAgIC8vIENvbGxlY3Qgb25seSBmcm9tIGhlYWRsaXN0LCBhdmVyYWdlIGVhY2ggaGVhZCwgdHJhbnNwb3NlIHRvIGVhc2UgaXRlcmF0aW9uXG4gICAgaWYgKGhlYWRMaXN0Lmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByb3dzOiBbW11dLFxuICAgICAgICAgICAgbGFiZWxzOiBbXSxcbiAgICAgICAgICAgIG1heDogMCxcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBkaW0gPSBudWxsXG4gICAgLy8gT25seSBjaGFuZ2UgdGhlIGF0dGVudGlvbiBncmFwaCBvcHBvc2l0ZSBzZWxlY3RlZCB0b2tlblxuICAgIGlmICh0b2tlbiAhPSBudWxsICYmICh0b2tlbi5zaWRlICE9IHNpZGUpKSB7XG4gICAgICAgIGRpbSA9IHRva2VuLnNpZGUgPT0gXCJsZWZ0XCIgPyAtMiA6IC0xIC8vIEFzc2lnbiB0byBcImZyb21cIiBkaXJlY3Rpb24gaWYgXCJsZWZ0XCIgXG4gICAgfVxuXG4gICAgbGV0IGF4aXM6IG51bWJlciA9IHNpZGUgPT0gXCJsZWZ0XCIgPyAyIDogMTtcblxuICAgIC8vIGF2ZXJhZ2UgYWNyb3NzIHRoZSBheGlzIHJlcHJlc2VudGluZyB0aGUgYXR0ZW50aW9ucy5cbiAgICBsZXQgZ2F0aGVyZWRNYXQgPSB0Zi50ZW5zb3IzZChoZWFkTWF0KVxuICAgIGlmIChkaW0gIT0gbnVsbCkge1xuICAgICAgICBnYXRoZXJlZE1hdCA9IGdhdGhlcmVkTWF0LmdhdGhlcihbdG9rZW4uaW5kXSwgZGltKVxuICAgIH1cbiAgICBsZXQgbmV3TWF0ID0gZ2F0aGVyZWRNYXQuZ2F0aGVyKGhlYWRMaXN0LCAwKS5tZWFuKFtheGlzXSkudHJhbnNwb3NlKCk7XG5cbiAgICBjb25zdCByb3dJbmZvID0gPG51bWJlcltdW10+bmV3TWF0LmFycmF5U3luYygpO1xuXG4gICAgY29uc3Qgb3V0OiBBdHRlbnRpb25IZWFkQm94SSA9IHtcbiAgICAgICAgcm93czogcm93SW5mbyxcbiAgICAgICAgbGFiZWxzOiBoZWFkTGlzdCxcbiAgICAgICAgbWF4OiA8bnVtYmVyPm5ld01hdC5tYXgoKS5hcnJheVN5bmMoKSxcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0XG59XG5cbmludGVyZmFjZSBDdXJyZW50T3B0aW9ucyB7XG4gICAgaGVhZEhlaWdodDogbnVtYmVyXG4gICAgaGVhZFdpZHRoOiBudW1iZXJcbiAgICB4UGFkOiBudW1iZXJcbiAgICB5UGFkOiBudW1iZXJcbiAgICBib3hXaWR0aDogbnVtYmVyXG4gICAgdG90YWxXaWR0aDogbnVtYmVyXG4gICAgdG90YWxIZWlnaHQ6IG51bWJlclxufTtcblxuZXhwb3J0IGNsYXNzIEF0dGVudGlvbkhlYWRCb3ggZXh0ZW5kcyBWQ29tcG9uZW50PEF0dGVudGlvbkhlYWRCb3hJPntcbiAgICBjc3NfbmFtZSA9ICcnO1xuICAgIHJvd0Nzc05hbWUgPSAnYXR0LWhlYWQnO1xuICAgIGJveENzc05hbWUgPSAnYXR0LXJlY3QnO1xuXG4gICAgc3RhdGljIGV2ZW50cyA9IHtcbiAgICAgICAgcm93TW91c2VPdmVyOiBcIkF0dGVudGlvbkhlYWRCb3hfUm93TW91c2VPdmVyXCIsXG4gICAgICAgIHJvd01vdXNlT3V0OiBcIkF0dGVudGlvbkhlYWRCb3hfUm93TW91c2VPdXRcIixcbiAgICAgICAgYm94TW91c2VPdmVyOiBcIkF0dGVudGlvbkhlYWRCb3hfQm94TW91c2VPdmVyXCIsXG4gICAgICAgIGJveE1vdXNlT3V0OiBcIkF0dGVudGlvbkhlYWRCb3hfQm94TW91c2VPdXRcIixcbiAgICAgICAgYm94TW91c2VNb3ZlOiBcIkF0dGVudGlvbkhlYWRCb3hfQm94TW91c2VNb3ZlXCIsXG4gICAgICAgIGJveENsaWNrOiBcIkF0dGVudGlvbkhlYWRCb3hfQm94Q2xpY2tcIixcbiAgICB9O1xuXG4gICAgX2RhdGE6IEF0dGVudGlvbkhlYWRCb3hJO1xuXG4gICAgX2N1cnJlbnQ6IFBhcnRpYWw8Q3VycmVudE9wdGlvbnM+ID0ge31cblxuICAgIG9wdGlvbnMgPSB7XG4gICAgICAgIGJveERpbTogMjYsXG4gICAgICAgIHlzY2FsZTogMSwgLy8gQW1vdW50IHRvIHNjYWxlIGJveGhlaWdodCB0byBnZXQgaW5kaXZpZHVhbCBoZWFkc1xuICAgICAgICB4c2NhbGU6IDAuNSwgLy8gQW1vdW50IHRvIHNjYWxlIGJveHdpZHRoIHRvIGdldCBpbmRpdmlkdWFsIGhlYWRzXG4gICAgICAgIHNpZGU6IFwibGVmdFwiLFxuICAgICAgICBtYXhXaWR0aDogMjAwLCAvLyBNYXhpbXVtIHdpZHRoIG9mIFNWR1xuICAgICAgICBvZmZzZXQ6IDAsIC8vIENoYW5nZSB0byAxIGlmIHlvdSBkZXNpcmUgdGhlIG9mZnNldCB2aXN1YWxpemF0aW9uIGZvciBBdXRvcmVncmVzc2l2ZSBtb2RlbHNcbiAgICB9O1xuXG4gICAgLy8gRDMgQ29tcG9uZW50c1xuICAgIGhlYWRSb3dzOiBEM1NlbDtcbiAgICBoZWFkQ2VsbHM6IEQzU2VsO1xuICAgIG9wYWNpdHlTY2FsZTogZDMuU2NhbGVMaW5lYXI8YW55LCBhbnk+O1xuXG4gICAgY29uc3RydWN0b3IoZDNQYXJlbnQ6IEQzU2VsLCBldmVudEhhbmRsZXI/OiBTaW1wbGVFdmVudEhhbmRsZXIsIG9wdGlvbnM6IHt9ID0ge30pIHtcbiAgICAgICAgc3VwZXIoZDNQYXJlbnQsIGV2ZW50SGFuZGxlcik7XG4gICAgICAgIHRoaXMuc3VwZXJJbml0U1ZHKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLl9pbml0KClcbiAgICB9XG5cbiAgICBfaW5pdCgpIHtcbiAgICAgICAgdGhpcy5oZWFkUm93cyA9IHRoaXMuYmFzZS5zZWxlY3RBbGwoYC4ke3RoaXMucm93Q3NzTmFtZX1gKVxuICAgICAgICB0aGlzLmhlYWRDZWxscyA9IHRoaXMuaGVhZFJvd3Muc2VsZWN0QWxsKGAke3RoaXMuYm94Q3NzTmFtZX1gKVxuICAgICAgICB0aGlzLm9wYWNpdHlTY2FsZSA9IGQzLnNjYWxlTGluZWFyKCkucmFuZ2UoWzAsIDFdKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUN1cnJlbnQoKTogUGFydGlhbDxDdXJyZW50T3B0aW9ucz4ge1xuICAgICAgICBjb25zdCBvcCA9IHRoaXMub3B0aW9uc1xuICAgICAgICBjb25zdCBjdXIgPSB0aGlzLl9jdXJyZW50XG5cbiAgICAgICAgY29uc3QgbkhlYWRzID0gdGhpcy5fZGF0YS5yb3dzWzBdLmxlbmd0aFxuICAgICAgICBjb25zdCBiYXNlSGVhZFdpZHRoID0gb3AuYm94RGltICogb3AueHNjYWxlXG5cbiAgICAgICAgLy8gU2NhbGUgaGVhZHdpZHRoIGFjY29yZGluZyB0byBtYXhpbXVtIHdpZHRoXG4gICAgICAgIGNvbnN0IGdldEhlYWRTY2FsZSA9IChuSCkgPT4gKE1hdGgubWluKG9wLm1heFdpZHRoIC8gbkgsIGJhc2VIZWFkV2lkdGgpIC8gYmFzZUhlYWRXaWR0aCkgKiBvcC54c2NhbGU7XG5cbiAgICAgICAgY3VyLmhlYWRIZWlnaHQgPSBvcC5ib3hEaW0gKiBvcC55c2NhbGU7XG4gICAgICAgIGN1ci5oZWFkV2lkdGggPSBnZXRIZWFkU2NhbGUobkhlYWRzKSAqIG9wLmJveERpbTtcbiAgICAgICAgY3VyLnhQYWQgPSBjdXIuaGVhZFdpZHRoO1xuICAgICAgICBjdXIueVBhZCA9IChvcC5ib3hEaW0gLSBjdXIuaGVhZEhlaWdodCkgLyAyO1xuXG4gICAgICAgIGNvbnN0IGdldEJveFdpZHRoID0gKGhlYWRXaWR0aCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWF4QndpZHRoID0gMTAwO1xuICAgICAgICAgICAgY29uc3QgYndpZHRoID0gdGhpcy5fZGF0YS5yb3dzWzBdLmxlbmd0aCAqIGN1ci5oZWFkV2lkdGhcbiAgICAgICAgICAgIGNvbnN0IHNjYWxlID0gZDMuc2NhbGVMaW5lYXJcbiAgICAgICAgICAgIGlmIChid2lkdGggPiBtYXhCd2lkdGgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG5cbiAgICAgICAgY3VyLmJveFdpZHRoID0gKHRoaXMuX2RhdGEucm93c1swXS5sZW5ndGggKiBjdXIuaGVhZFdpZHRoKTtcbiAgICAgICAgY3VyLnRvdGFsV2lkdGggPSAoMiAqIGN1ci54UGFkKSArIGN1ci5ib3hXaWR0aDtcbiAgICAgICAgY3VyLnRvdGFsSGVpZ2h0ID0gKG9wLmJveERpbSAqICh0aGlzLl9kYXRhLnJvd3MubGVuZ3RoICsgb3Aub2Zmc2V0KSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZURhdGEoKSB7XG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgY29uc3QgYm94RXZlbnQgPSAoaSkgPT4geyByZXR1cm4geyBpbmQ6IGksIHNpZGU6IG9wLnNpZGUsIGhlYWQ6IHNlbGYuX2RhdGEubGFiZWxzW2ldIH0gfVxuICAgICAgICBjb25zdCBjdXIgPSB0aGlzLnVwZGF0ZUN1cnJlbnQoKVxuXG4gICAgICAgIGNvbnN0IGdldEJhc2VYID0gKCkgPT4gKDxIVE1MRWxlbWVudD5zZWxmLmJhc2Uubm9kZSgpKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0XG4gICAgICAgIGNvbnN0IGdldEJhc2VZID0gKCkgPT4gKDxIVE1MRWxlbWVudD5zZWxmLmJhc2Uubm9kZSgpKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3BcblxuICAgICAgICB0aGlzLmJhc2UuaHRtbCgnJyk7XG5cbiAgICAgICAgdGhpcy5wYXJlbnRcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgY3VyLnRvdGFsV2lkdGgpXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBjdXIudG90YWxIZWlnaHQpXG5cbiAgICAgICAgdGhpcy5oZWFkUm93cyA9IHRoaXMuYmFzZS5zZWxlY3RBbGwoYC4ke3NlbGYucm93Q3NzTmFtZX1gKVxuICAgICAgICAgICAgLmRhdGEoc2VsZi5fZGF0YS5yb3dzKVxuICAgICAgICAgICAgLmpvaW4oXCJnXCIpXG4gICAgICAgICAgICAuYXR0cnMoe1xuICAgICAgICAgICAgICAgIGNsYXNzOiAoZCwgaSkgPT4gYCR7c2VsZi5yb3dDc3NOYW1lfSAke3NlbGYucm93Q3NzTmFtZX0tJHtpfWAsXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU1ZHLnRyYW5zbGF0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBjdXIueFBhZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5OiAob3AuYm94RGltICogKGkgKyBvcC5vZmZzZXQpKSArIGN1ci55UGFkLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHdpZHRoOiBjdXIuYm94V2lkdGgsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiBjdXIuaGVhZEhlaWdodCxcblxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5vbihcIm1vdXNlb3ZlclwiLCAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIHNlbGYuZXZlbnRIYW5kbGVyLnRyaWdnZXIoQXR0ZW50aW9uSGVhZEJveC5ldmVudHMucm93TW91c2VPdmVyLCB7IGluZDogaSwgc2lkZTogb3Auc2lkZSB9KVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5vbihcIm1vdXNlb3V0XCIsIChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5yb3dNb3VzZU91dCwgeyBpbmQ6IGksIHNpZGU6IG9wLnNpZGUgfSlcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5oZWFkQ2VsbHMgPSB0aGlzLmhlYWRSb3dzXG4gICAgICAgICAgICAuc2VsZWN0QWxsKGAke3RoaXMuYm94Q3NzTmFtZX1gKVxuICAgICAgICAgICAgLmRhdGEoZCA9PiBkKVxuICAgICAgICAgICAgLmpvaW4oJ3JlY3QnKVxuICAgICAgICAgICAgLmF0dHJzKHtcbiAgICAgICAgICAgICAgICB4OiAoZCwgaSkgPT4gaSAqIGN1ci5oZWFkV2lkdGgsXG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICBjbGFzczogdGhpcy5ib3hDc3NOYW1lLFxuICAgICAgICAgICAgICAgIGhlYWQ6IChkLCBpKSA9PiBzZWxmLl9kYXRhLmxhYmVsc1tpXSxcbiAgICAgICAgICAgICAgICB3aWR0aDogY3VyLmhlYWRXaWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGN1ci5oZWFkSGVpZ2h0LFxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IChkOiBudW1iZXIpID0+IHRoaXMub3BhY2l0eVNjYWxlKGQpLFxuICAgICAgICAgICAgICAgIGZpbGw6IFwiYmx1ZVwiXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKFwibW91c2VvdmVyXCIsIChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hNb3VzZU92ZXIsIGJveEV2ZW50KGkpKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5vbihcIm1vdXNlb3V0XCIsIChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hNb3VzZU91dCwgYm94RXZlbnQoaSkpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKFwiY2xpY2tcIiwgKGQsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBzZWxmLmV2ZW50SGFuZGxlci50cmlnZ2VyKEF0dGVudGlvbkhlYWRCb3guZXZlbnRzLmJveENsaWNrLCBib3hFdmVudChpKSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oXCJtb3VzZW1vdmVcIiwgZnVuY3Rpb24oZCwgaSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wID0gc2VsZi5vcHRpb25zXG4gICAgICAgICAgICAgICAgY29uc3QgbW91c2UgPSBkMy5tb3VzZShzZWxmLmJhc2Uubm9kZSgpKVxuXG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hNb3VzZU1vdmUsIHsgaW5kOiBpLCBzaWRlOiBvcC5zaWRlLCBiYXNlWDogZ2V0QmFzZVgoKSwgYmFzZVk6IGdldEJhc2VZKCksIG1vdXNlOiBtb3VzZSB9KVxuXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmFwcGVuZChcInN2Zzp0aXRsZVwiKVxuICAgICAgICAgICAgLnRleHQoKGQsIGkpID0+IFwiSGVhZCBcIiArIChzZWxmLl9kYXRhLmxhYmVsc1tpXSArIDEpKVxuICAgIH1cblxuXG4gICAgX3dyYW5nbGUoZGF0YTogQXR0ZW50aW9uSGVhZEJveEkpIHtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMub3BhY2l0eVNjYWxlID0gdGhpcy5vcGFjaXR5U2NhbGUuZG9tYWluKFswLCBkYXRhLm1heF0pXG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIF9yZW5kZXIoZGF0YTogQXR0ZW50aW9uSGVhZEJveEkpIHtcbiAgICAgICAgdGhpcy51cGRhdGVEYXRhKCk7XG4gICAgfVxufSIsImltcG9ydCB7VkNvbXBvbmVudH0gZnJvbSAnLi9WaXNDb21wb25lbnQnXG5pbXBvcnQge3NwYWN5Q29sb3JzfSBmcm9tICcuLi9ldGMvU3BhY3lJbmZvJ1xuaW1wb3J0IHtTVkd9IGZyb20gJy4uL2V0Yy9TVkdwbHVzJ1xuaW1wb3J0ICogYXMgZDMgZnJvbSAnZDMnXG5pbXBvcnQgKiBhcyBSIGZyb20gJ3JhbWRhJ1xuaW1wb3J0IHsgRDNTZWwgfSBmcm9tICcuLi9ldGMvVXRpbCc7XG5pbXBvcnQgeyBTaW1wbGVFdmVudEhhbmRsZXIgfSBmcm9tICcuLi9ldGMvU2ltcGxlRXZlbnRIYW5kbGVyJztcblxuaW50ZXJmYWNlIE1hcmdpbkluZm8ge1xuICAgIHRvcDogbnVtYmVyLFxuICAgIGJvdHRvbTogbnVtYmVyLFxuICAgIHJpZ2h0OiBudW1iZXIsXG4gICAgbGVmdDogbnVtYmVyXG59XG5cbi8vIERlcGVuZGVudCBvbiB0aGUgb3B0aW9ucyBpbiB0aGUgcmVzcG9uc2VcbnR5cGUgTWF0Y2hlZE1ldGFTZWxlY3Rpb25zID0gXCJwb3NcIiB8IFwiZGVwXCIgfCBcImVudFwiXG5cbmludGVyZmFjZSBNYXRjaGVkTWV0YUNvdW50IHtcbiAgICBwb3M6IG51bWJlclxuICAgIGRlcDogbnVtYmVyXG4gICAgaXNfZW50OiBudW1iZXJcbn1cblxuaW50ZXJmYWNlIE1heEF0dE1ldGFDb3VudCB7XG4gICAgb2Zmc2V0OiBudW1iZXJcbn1cblxudHlwZSBNYXRjaGVkRGF0YUludGVyZmFjZSA9IE1hdGNoZWRNZXRhQ291bnRcbnR5cGUgTWF4QXR0RGF0YUludGVyZmFjZSA9IE1heEF0dE1ldGFDb3VudFxudHlwZSBEYXRhSW50ZXJmYWNlID0gTWF0Y2hlZERhdGFJbnRlcmZhY2UgfCBNYXhBdHREYXRhSW50ZXJmYWNlXG5cbmludGVyZmFjZSBDb3VudGVkSGlzdCB7XG4gICAgbGFiZWw6IHN0cmluZyxcbiAgICBjb3VudDogbnVtYmVyXG59XG5cbnR5cGUgUmVuZGVyRGF0YUludGVyZmFjZSA9IENvdW50ZWRIaXN0W11cblxuXG4vKipcbiAqICBEYXRhIGZvcm1hdHRpbmcgZnVuY3Rpb25zXG4gKi9cbmNvbnN0IHRvUmVuZGVyRGF0YSA9IChvYmo6IHtbczogc3RyaW5nXTogbnVtYmVyfSk6IFJlbmRlckRhdGFJbnRlcmZhY2UgPT4gT2JqZWN0LmtleXMob2JqKS5tYXAoKGssIGkpID0+IHtcbiAgICByZXR1cm4ge2xhYmVsOiBrLCBjb3VudDogb2JqW2tdfVxufSlcblxuY29uc3QgdG9TdHJpbmdPck51bSA9IChhOnN0cmluZykgPT4ge1xuICAgIGNvbnN0IG5hID0gK2FcbiAgICBpZiAoaXNOYU4obmEpKSB7XG4gICAgICAgIHJldHVybiBhXG4gICAgfVxuICAgIHJldHVybiBuYVxufVxuXG5jb25zdCBzb3J0QnlMYWJlbCA9IFIuc29ydEJ5KFIuY29tcG9zZSh0b1N0cmluZ09yTnVtLCBSLnByb3AoJ2xhYmVsJykpKVxuY29uc3Qgc29ydEJ5Q291bnQgPSBSLnNvcnRCeShSLnByb3AoJ2NvdW50JykpXG5cbmNvbnN0IHRvT3JkZXJlZFJlbmRlciA9IFIuY29tcG9zZShcbiAgICBSLnJldmVyc2UsXG4gICAgLy8gQHRzLWlnbm9yZSAtLSBUT0RPOiBmaXhcbiAgICBzb3J0QnlDb3VudCxcbiAgICB0b1JlbmRlckRhdGFcbilcblxuZXhwb3J0IGNsYXNzIENvcnB1c0hpc3RvZ3JhbTxUPiBleHRlbmRzIFZDb21wb25lbnQ8VD4ge1xuXG4gICAgY3NzX25hbWUgPSAnJ1xuXG4gICAgc3RhdGljIGV2ZW50cyA9IHt9XG5cbiAgICBfY3VycmVudCA9IHtcbiAgICAgICAgY2hhcnQ6IHtcbiAgICAgICAgICAgIGhlaWdodDogbnVsbCxcbiAgICAgICAgICAgIHdpZHRoOiBudWxsXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEMyBDT01QT05FTlRTXG4gICAgc3ZnOiBEM1NlbFxuXG4gICAgb3B0aW9uczoge1xuICAgICAgICBtYXJnaW46IE1hcmdpbkluZm9cbiAgICAgICAgYmFyV2lkdGg6IG51bWJlclxuICAgICAgICB3aWR0aDogbnVtYmVyXG4gICAgICAgIGhlaWdodDogbnVtYmVyXG4gICAgICAgIHZhbDogc3RyaW5nXG4gICAgICAgIHhMYWJlbFJvdDogbnVtYmVyXG4gICAgICAgIHhMYWJlbE9mZnNldDogbnVtYmVyXG4gICAgICAgIHlMYWJlbE9mZnNldDogbnVtYmVyXG4gICAgfVxuXG4gICAgYXhlcyA9IHtcbiAgICAgICAgeDogZDMuc2NhbGVCYW5kKCksXG4gICAgICAgIHk6IGQzLnNjYWxlTGluZWFyKCksXG4gICAgfVxuXG5cbiAgICBjb25zdHJ1Y3RvcihkM3BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86IFNpbXBsZUV2ZW50SGFuZGxlciwgb3B0aW9ucz17fSkge1xuICAgICAgICBzdXBlcihkM3BhcmVudCwgZXZlbnRIYW5kbGVyKVxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgICBtYXJnaW46IHtcbiAgICAgICAgICAgICAgICB0b3A6IDEwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAzMCxcbiAgICAgICAgICAgICAgICBib3R0b206IDUwLFxuICAgICAgICAgICAgICAgIGxlZnQ6IDQwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYmFyV2lkdGg6IDI1LFxuICAgICAgICAgICAgd2lkdGg6IDE4NSxcbiAgICAgICAgICAgIGhlaWdodDogMjMwLFxuICAgICAgICAgICAgdmFsOiBcInBvc1wiLCAvLyBDaGFuZ2UgRGVmYXVsdCwgcGFzcyB0aHJvdWdoIGNvbnN0cnVjdG9yXG4gICAgICAgICAgICB4TGFiZWxSb3Q6IDQ1LFxuICAgICAgICAgICAgeExhYmVsT2Zmc2V0OiAxNSxcbiAgICAgICAgICAgIHlMYWJlbE9mZnNldDogNSxcblxuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3VwZXJJbml0U1ZHKClcbiAgICB9XG5cbiAgICBtZXRhKCk6TWF0Y2hlZE1ldGFTZWxlY3Rpb25zXG4gICAgbWV0YSh2YWw6TWF0Y2hlZE1ldGFTZWxlY3Rpb25zKTogdGhpc1xuICAgIG1ldGEodmFsPykge1xuICAgICAgICBpZiAodmFsID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMudmFsO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5vcHRpb25zLnZhbCA9IHZhbDtcbiAgICAgICAgdGhpcy51cGRhdGUodGhpcy5fZGF0YSlcblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBfaW5pdCgpIHt9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVhBeGlzKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgY29uc3Qgb3AgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IHdpZHRoID0gb3Aud2lkdGggLSBvcC5tYXJnaW4ubGVmdCAtIG9wLm1hcmdpbi5yaWdodFxuXG4gICAgICAgIHRoaXMuYXhlcy54XG4gICAgICAgICAgICAuZG9tYWluKFIubWFwKFIucHJvcCgnbGFiZWwnKSwgc2VsZi5yZW5kZXJEYXRhKSlcbiAgICAgICAgICAgIC5yYW5nZVJvdW5kKFswLCB3aWR0aF0pXG4gICAgICAgICAgICAucGFkZGluZygwLjEpXG5cbiAgICAgICAgdGhpcy5fY3VycmVudC5jaGFydC53aWR0aCA9IHdpZHRoO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlWUF4aXMoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBjb25zdCBvcCA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gb3AuaGVpZ2h0IC0gb3AubWFyZ2luLnRvcCAtIG9wLm1hcmdpbi5ib3R0b21cblxuICAgICAgICB0aGlzLmF4ZXMueVxuICAgICAgICAgICAgLmRvbWFpbihbMCwgK2QzLm1heChSLm1hcChSLnByb3AoJ2NvdW50JyksIHNlbGYucmVuZGVyRGF0YSkpXSlcbiAgICAgICAgICAgIC5yYW5nZVJvdW5kKFtoZWlnaHQsIDBdKVxuXG4gICAgICAgIHRoaXMuX2N1cnJlbnQuY2hhcnQuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlQXhlcygpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVYQXhpcygpXG4gICAgICAgIHRoaXMuY3JlYXRlWUF4aXMoKVxuICAgIH1cblxuICAgIF93cmFuZ2xlKGRhdGE6IERhdGFJbnRlcmZhY2UpIHtcbiAgICAgICAgY29uc3Qgb3V0ID0gZGF0YVt0aGlzLm9wdGlvbnMudmFsXVxuICAgICAgICByZXR1cm4gdG9PcmRlcmVkUmVuZGVyKG91dClcbiAgICB9XG5cbiAgICB3aWR0aCgpOm51bWJlclxuICAgIHdpZHRoKHZhbDpudW1iZXIpOnRoaXNcbiAgICB3aWR0aCh2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy53aWR0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9wdGlvbnMud2lkdGggPSB2YWw7XG4gICAgICAgIHRoaXMudXBkYXRlV2lkdGgoKTtcbiAgICAgICAgdGhpcy5jcmVhdGVYQXhpcygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBoZWlnaHQoKTpudW1iZXJcbiAgICBoZWlnaHQodmFsOm51bWJlcik6dGhpc1xuICAgIGhlaWdodCh2YWw/KSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5oZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9wdGlvbnMuaGVpZ2h0ID0gdmFsO1xuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLmNyZWF0ZVlBeGlzKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlV2lkdGgoKSB7XG4gICAgICAgIHRoaXMuc3ZnLmF0dHIoJ3dpZHRoJywgdGhpcy5vcHRpb25zLndpZHRoKVxuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlSGVpZ2h0KCkge1xuICAgICAgICB0aGlzLnN2Zy5hdHRyKCdoZWlnaHQnLCB0aGlzLm9wdGlvbnMuaGVpZ2h0KVxuICAgIH1cblxuICAgIHByaXZhdGUgZmlnV2lkdGgoZGF0YTogUmVuZGVyRGF0YUludGVyZmFjZSkge1xuICAgICAgICBjb25zdCBvcCA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgcmV0dXJuIChkYXRhLmxlbmd0aCAqIG9wLmJhcldpZHRoKSArIG9wLm1hcmdpbi5sZWZ0ICsgb3AubWFyZ2luLnJpZ2h0XG4gICAgfVxuXG4gICAgX3JlbmRlcihkYXRhOlJlbmRlckRhdGFJbnRlcmZhY2UpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBjdXJyID0gdGhpcy5fY3VycmVudDtcblxuICAgICAgICB0aGlzLnBhcmVudC5odG1sKCcnKVxuICAgICAgICB0aGlzLnN2ZyA9IHRoaXMucGFyZW50XG5cbiAgICAgICAgdGhpcy5jcmVhdGVBeGVzKCk7XG4gICAgICAgIHRoaXMud2lkdGgodGhpcy5maWdXaWR0aChkYXRhKSk7XG4gICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBheGVzXG4gICAgICAgIGNvbnN0IGcgPSBzZWxmLnN2Zy5hcHBlbmQoXCJnXCIpXG4gICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBTVkcudHJhbnNsYXRlKHt4OiBvcC5tYXJnaW4ubGVmdCwgeTpvcC5tYXJnaW4udG9wfSkpXG5cbiAgICAgICAgLy8gSGFjayB0byBhbGxvdyBjbGVhcmluZyB0aGlzIGhpc3RvZ3JhbXMgdG8gd29ya1xuICAgICAgICBzZWxmLmJhc2UgPSBnXG5cbiAgICAgICAgLy8gRml4IGJlbG93IGZvciBwb3NpdGlvbmFsIGNoYW5naW5nXG4gICAgICAgICAgICBjb25zdCBheGlzQm90dG9tID0gZy5hcHBlbmQoXCJnXCIpXG4gICAgICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgU1ZHLnRyYW5zbGF0ZSh7eDogMCwgeTpjdXJyLmNoYXJ0LmhlaWdodH0pKVxuICAgICAgICAgICAgICAgIC5jYWxsKGQzLmF4aXNCb3R0b20oc2VsZi5heGVzLngpKVxuXG4gICAgICAgICAgICBpZiAob3AudmFsICE9IFwib2Zmc2V0XCIpIHtcbiAgICAgICAgICAgICAgICBheGlzQm90dG9tXG4gICAgICAgICAgICAgICAgICAgIC5zZWxlY3RBbGwoXCJ0ZXh0XCIpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKFwieVwiLCBvcC55TGFiZWxPZmZzZXQpICAgLy8gTW92ZSBiZWxvdyB0aGUgYXhpc1xuICAgICAgICAgICAgICAgICAgICAuYXR0cihcInhcIiwgb3AueExhYmVsT2Zmc2V0KSAgLy8gT2Zmc2V0IHRvIHRoZSByaWdodCBhIGJpdFxuICAgICAgICAgICAgICAgICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBTVkcucm90YXRlKG9wLnhMYWJlbFJvdCkpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGcuYXBwZW5kKFwiZ1wiKVxuICAgICAgICAgICAgICAgIC5jYWxsKGQzLmF4aXNMZWZ0KHNlbGYuYXhlcy55KSlcblxuICAgICAgICBnLnNlbGVjdEFsbChcIi5iYXJcIilcbiAgICAgICAgICAuZGF0YShkYXRhKVxuICAgICAgICAgIC5qb2luKCdyZWN0JylcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJiYXJcIilcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBzZWxmLmF4ZXMueChkLmxhYmVsKTsgfSlcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBzZWxmLmF4ZXMueShkLmNvdW50KTsgfSlcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgc2VsZi5heGVzLnguYmFuZHdpZHRoKCkpXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBjdXJyLmNoYXJ0LmhlaWdodCAtIHNlbGYuYXhlcy55KGQuY291bnQpOyB9KVxuICAgICAgICAgICAgLnN0eWxlKCdmaWxsJywgayA9PiBzcGFjeUNvbG9ycy5jb2xvclNjYWxlW29wLnZhbF0oay5sYWJlbCkpXG4gICAgfVxufVxuIiwiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgKiBhcyBSIGZyb20gJ3JhbWRhJ1xuaW1wb3J0ICdkMy1zZWxlY3Rpb24tbXVsdGknXG5pbXBvcnQge2QzUywgRDNTZWx9IGZyb20gXCIuLi9ldGMvVXRpbFwiO1xuaW1wb3J0IHsgVkNvbXBvbmVudCB9IGZyb20gXCIuL1Zpc0NvbXBvbmVudFwiO1xuaW1wb3J0IHsgU2ltcGxlRXZlbnRIYW5kbGVyIH0gZnJvbSBcIi4uL2V0Yy9TaW1wbGVFdmVudEhhbmRsZXJcIjtcbmltcG9ydCAqIGFzIHRwIGZyb20gXCIuLi9ldGMvdHlwZXNcIlxuaW1wb3J0ICcuLi9ldGMveGQzJ1xuXG4vLyBIZWxwZXJzXG5jb25zdCBjdXJyTWF0Y2hJZHggPSAoZWxlbSkgPT4gKyg8RWxlbWVudD5lbGVtLnBhcmVudE5vZGUpLmdldEF0dHJpYnV0ZSgnbWF0Y2hpZHgnKVxuY29uc3QgY3VyclJvd051bSA9IChlbGVtKSA9PiArKDxFbGVtZW50PmVsZW0ucGFyZW50Tm9kZSkuZ2V0QXR0cmlidXRlKCdyb3dudW0nKVxuY29uc3QgYmFja2dyb3VuZENvbG9yID0geCA9PiBgcmdiYSgxMjgsIDAsIDE1MCwgJHswLjYqeH0pYFxuXG5leHBvcnQgY2xhc3MgQ29ycHVzSW5zcGVjdG9yIGV4dGVuZHMgVkNvbXBvbmVudDx0cC5GYWlzc1NlYXJjaFJlc3VsdHNbXT57XG4gICAgY3NzX25hbWUgPSAnY29ycHVzLWluc3BlY3Rvcic7XG4gICAgX2N1cnJlbnQ6IHt9O1xuXG4gICAgX2RhdGE6IHRwLkZhaXNzU2VhcmNoUmVzdWx0c1tdOyAvLyBUaGUgcGFzc2VkIGRhdGFcblxuICAgIHN0YXRpYyBldmVudHMgPSB7XG4gICAgICAgIHJvd01vdXNlT3ZlcjogXCJDb3JwdXNJbnNwZWN0b3Jfcm93TW91c2VPdmVyXCIsXG4gICAgICAgIHJvd01vdXNlT3V0OiBcIkNvcnB1c0luc3BlY3Rvcl9yb3dNb3VzZU91dFwiLFxuICAgICAgICByb3dDbGljazogXCJDb3JwdXNJbnNwZWN0b3Jfcm93Q2xpY2tcIixcbiAgICAgICAgcm93RGJsQ2xpY2s6IFwiQ29ycHVzSW5zcGVjdG9yX3Jvd0RibENsaWNrXCIsXG4gICAgICAgIGNlbGxNb3VzZU92ZXI6IFwiQ29ycHVzSW5zcGVjdG9yX2NlbGxNb3VzZU92ZXJcIixcbiAgICAgICAgY2VsbE1vdXNlT3V0OiBcIkNvcnB1c0luc3BlY3Rvcl9jZWxsTW91c2VPdXRcIixcbiAgICAgICAgY2VsbENsaWNrOiBcIkNvcnB1c0luc3BlY3Rvcl9jZWxsQ2xpY2tcIixcbiAgICAgICAgY2VsbERibENsaWNrOiBcIkNvcnB1c0luc3BlY3Rvcl9jZWxsRGJsQ2xpY2tcIixcbiAgICB9XG5cbiAgICBvcHRpb25zID0ge1xuICAgICAgICBzaG93TmV4dDogZmFsc2VcbiAgICB9XG5cbiAgICAvLyBDT01QT05FTlRTXG4gICAgaW5zcGVjdG9yUm93czogRDNTZWxcbiAgICBpbnNwZWN0b3JDZWxsczogRDNTZWxcbiAgICBzY2FsZXIgPSBkMy5zY2FsZVBvdygpLnJhbmdlKFswLDAuOV0pLmV4cG9uZW50KDIpXG5cbiAgICBjb25zdHJ1Y3RvcihkM1BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86U2ltcGxlRXZlbnRIYW5kbGVyLCBvcHRpb25zOiB7fSA9IHt9KSB7XG4gICAgICAgIHN1cGVyKGQzUGFyZW50LCBldmVudEhhbmRsZXIpXG4gICAgICAgIHRoaXMuc3VwZXJJbml0SFRNTChvcHRpb25zKVxuICAgICAgICB0aGlzLl9pbml0KClcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZVJvd3MoKSB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhXG5cbiAgICAgICAgdGhpcy5pbnNwZWN0b3JSb3dzID0gdGhpcy5iYXNlLnNlbGVjdEFsbChcIi5pbnNwZWN0b3Itcm93XCIpXG4gICAgICAgICAgICAuZGF0YShkYXRhKVxuICAgICAgICAgICAgLmpvaW4oJ2RpdicpXG4gICAgICAgICAgICAuY2xhc3NlZCgnaW5zcGVjdG9yLXJvdycsIHRydWUpXG4gICAgICAgICAgICAuYXR0cnMoe1xuICAgICAgICAgICAgICAgIG1hdGNoSWR4OiBkID0+IGQuaW5kZXgsXG4gICAgICAgICAgICAgICAgcm93TnVtOiAoZCwgaSkgPT4gaSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oXCJtb3VzZW92ZXJcIiwgKGQsIGkpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIudHJpZ2dlcihDb3JwdXNJbnNwZWN0b3IuZXZlbnRzLnJvd01vdXNlT3Zlciwge30pXG4gICAgICAgICAgICB9KVxuICAgIH1cblxuICAgIHByaXZhdGUgYWRkVG9vbHRpcCgpIHtcbiAgICAgICAgdGhpcy5pbnNwZWN0b3JDZWxscyA9IHRoaXMuaW5zcGVjdG9yQ2VsbHNcbiAgICAgICAgICAgIC5jbGFzc2VkKCdjZWxsdG9vbHRpcCcsIHRydWUpXG4gICAgICAgICAgICAuYXBwZW5kKCdzcGFuJylcbiAgICAgICAgICAgIC5jbGFzc2VkKCd0b29sdGlwdGV4dCcsIHRydWUpXG4gICAgICAgICAgICAuaHRtbCgoZCwgaSwgbikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVudGl0eVN0ciA9IGQuaXNfZW50ID8gXCI8YnI+RW50aXR5XCIgOiBcIlwiXG4gICAgICAgICAgICAgICAgY29uc3QgYXR0ID0gKDxFbGVtZW50Pm5baV0ucGFyZW50Tm9kZSkuZ2V0QXR0cmlidXRlKCdhdHQnKS5zbGljZSgwLCA3KVxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dFN0ciA9IGA8YnI+QXR0ZW50aW9uOiAke2F0dH1gXG5cbiAgICAgICAgICAgICAgICByZXR1cm4gYFBPUzogJHtkLnBvcy50b0xvd2VyQ2FzZSgpfTxicj5ERVA6ICR7ZC5kZXAudG9Mb3dlckNhc2UoKX1gICsgZW50aXR5U3RyICsgYXR0U3RyXG4gICAgICAgICAgICB9KVxuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlQ2VsbHMoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzXG5cbiAgICAgICAgdGhpcy5pbnNwZWN0b3JDZWxscyA9IHRoaXMuaW5zcGVjdG9yUm93cy5zZWxlY3RBbGwoJy5pbnNwZWN0b3ItY2VsbCcpXG4gICAgICAgICAgICAuZGF0YSgoZDp0cC5GYWlzc1NlYXJjaFJlc3VsdHMpID0+IGQudG9rZW5zKVxuICAgICAgICAgICAgLmpvaW4oJ2RpdicpXG4gICAgICAgICAgICAuY2xhc3NlZCgnaW5zcGVjdG9yLWNlbGwnLCB0cnVlKVxuICAgICAgICAgICAgLmF0dHIoJ2luZGV4LW9mZnNldCcsIChkLCBpLCBuOkhUTUxFbGVtZW50W10pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRjaElkeCA9IGN1cnJNYXRjaElkeChuW2ldKVxuICAgICAgICAgICAgICAgIHJldHVybiBpIC0gbWF0Y2hJZHggXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmF0dHJzKHtcbiAgICAgICAgICAgICAgICBwb3M6IGQgPT4gZC5wb3MudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAgICAgICBkZXA6IGQgPT4gZC5kZXAudG9Mb3dlckNhc2UoKSwgXG4gICAgICAgICAgICAgICAgaXNfZW50OiBkID0+IGQuaXNfZW50XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRleHQoZCA9PiBkLnRva2VuLnJlcGxhY2UoXCJcXHUwMTIwXCIsIFwiIFwiKSlcbiAgICAgICAgICAgIC5jbGFzc2VkKCdtYXRjaGVkLWNlbGwnLCBkID0+IGQuaXNfbWF0Y2gpXG4gICAgICAgICAgICAuY2xhc3NlZCgnbmV4dC1jZWxsJywgZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnNob3dOZXh0KCkgJiYgZC5pc19uZXh0X3dvcmRcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2xhc3NlZCgnZ3JheS1jZWxsJywgZnVuY3Rpb24oZCwgaSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlkeCA9ICtjdXJyTWF0Y2hJZHgodGhpcylcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zaG93TmV4dCgpICYmIGkgPiBpZHhcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgLy8gSGlnaGxpZ2h0IHRoZSBjZWxscyBhcHByb3ByaWF0ZWx5XG4gICAgICAgIHRoaXMuaW5zcGVjdG9yQ2VsbHMuZWFjaCgoZCxpLG4pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlkeCA9IGN1cnJNYXRjaElkeChuW2ldKVxuICAgICAgICAgICAgaWYgKGkgPT0gaWR4KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXR0ID0gZC5pbndhcmRcbiAgICAgICAgICAgICAgICBjb25zdCBtYXhBdHQgPSArZDMubWF4KGF0dClcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyUm93ID0gY3VyclJvd051bShuW2ldKVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxlciA9IHNlbGYuc2NhbGVyLmRvbWFpbihbMCwgbWF4QXR0XSlcblxuICAgICAgICAgICAgICAgIGQzLnNlbGVjdEFsbChgLmluc3BlY3Rvci1yb3dbcm93bnVtPScke2N1cnJSb3d9J11gKVxuICAgICAgICAgICAgICAgICAgICAuc2VsZWN0QWxsKGAuaW5zcGVjdG9yLWNlbGxgKVxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoJ2JhY2tncm91bmQnLCAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhY2tncm91bmRDb2xvcihzY2FsZXIoYXR0W2ldKSlcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2F0dCcsIChkLCBpKSA9PiBhdHRbaV0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgc2VsZi5hZGRUb29sdGlwKClcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZURhdGEoKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlUm93cygpXG4gICAgICAgIHRoaXMuY3JlYXRlQ2VsbHMoKVxuICAgIH1cblxuICAgIF9pbml0KCkge31cblxuICAgIF93cmFuZ2xlKGRhdGE6IHRwLkZhaXNzU2VhcmNoUmVzdWx0c1tdKSB7XG4gICAgICAgIHRoaXMuX2RhdGEgPSBkYXRhXG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIF9yZW5kZXIoZGF0YTogdHAuRmFpc3NTZWFyY2hSZXN1bHRzW10pIHtcbiAgICAgICAgLy8gUmVtZW1iZXIgdGhhdCB0aGlzLl9kYXRhIGlzIGRlZmluZWQgaW4gd3JhbmdsZSB3aGljaCBzaG91bGQgYWx3YXlzIGJlIGNhbGxlZCBiZWZvcmUgcmVuZGVyXG4gICAgICAgIC8vIGFzIGlzIGRlZmluZWQgaW4gdGhlIHVwZGF0ZSBmdW5jdGlvblxuICAgICAgICB0aGlzLnVwZGF0ZURhdGEoKVxuICAgIH1cblxuICAgIHNob3dOZXh0KCk6IGJvb2xlYW5cbiAgICBzaG93TmV4dCh2OmJvb2xlYW4pOiB0aGlzXG4gICAgc2hvd05leHQodj8pIHtcbiAgICAgICAgaWYgKHYgPT0gbnVsbCkgcmV0dXJuIHRoaXMub3B0aW9ucy5zaG93TmV4dFxuXG4gICAgICAgIHRoaXMub3B0aW9ucy5zaG93TmV4dCA9IHZcbiAgICAgICAgcmV0dXJuIHRoaXNcbiAgICB9XG59IiwiaW1wb3J0ICogYXMgZDMgZnJvbSAnZDMnXG5pbXBvcnQgKiBhcyBSIGZyb20gJ3JhbWRhJ1xuaW1wb3J0ICogYXMgdHAgZnJvbSAnLi4vZXRjL3R5cGVzJ1xuaW1wb3J0IHsgRDNTZWwgfSBmcm9tICcuLi9ldGMvVXRpbCdcbmltcG9ydCB7IFZDb21wb25lbnQgfSBmcm9tICcuLi92aXMvVmlzQ29tcG9uZW50J1xuaW1wb3J0IHsgU2ltcGxlRXZlbnRIYW5kbGVyIH0gZnJvbSBcIi4uL2V0Yy9TaW1wbGVFdmVudEhhbmRsZXJcIjtcbmltcG9ydCB7IFNWRyB9IGZyb20gXCIuLi9ldGMvU1ZHcGx1c1wiXG5pbXBvcnQgeyBzcGFjeUNvbG9ycyB9IGZyb20gXCIuLi9ldGMvU3BhY3lJbmZvXCJcbmltcG9ydCBcIi4uL2V0Yy94ZDNcIlxuXG4vLyBOZWVkIGFkZGl0b2luYWwgaGVpZ2h0IGluZm9ybWF0aW9uIHRvIHJlbmRlciBib3hlc1xuaW50ZXJmYWNlIEJhc2VEYXRhSW50ZXJmYWNlIGV4dGVuZHMgdHAuRmFpc3NTZWFyY2hSZXN1bHRzIHtcbiAgICBoZWlnaHQ6IG51bWJlclxufVxudHlwZSBEYXRhSW50ZXJmYWNlID0gQmFzZURhdGFJbnRlcmZhY2VbXVxuXG5pbnRlcmZhY2UgQ29sb3JNZXRhQmFzZURhdGEge1xuICAgIHBvczogc3RyaW5nXG4gICAgZGVwOiBzdHJpbmdcbiAgICBpc19lbnQ6IGJvb2xlYW5cbiAgICB0b2tlbjogc3RyaW5nXG59XG5cbnR5cGUgRGlzcGxheU9wdGlvbnMgPSBcInBvc1wiIHwgXCJkZXBcIiB8IFwiZW50XCJcblxuZnVuY3Rpb24gbWFuYWdlckRhdGEyTWF0RGF0YShkYXRhSW46IERhdGFJbnRlcmZhY2UsIGluZGV4T2Zmc2V0ID0gMCwgdG9QaWNrID0gWydwb3MnXSkge1xuXG4gICAgY29uc3Qgb3V0T2ZSYW5nZU9iajogQ29sb3JNZXRhQmFzZURhdGEgPSB7XG4gICAgICAgIHBvczogbnVsbCxcbiAgICAgICAgZGVwOiBudWxsLFxuICAgICAgICBpc19lbnQ6IG51bGwsXG4gICAgICAgIHRva2VuOiBudWxsLFxuICAgIH1cblxuICAgIGNvbnN0IGNob29zZVByb3BzID0gUi5waWNrKHRvUGljaylcblxuICAgIGNvbnN0IGRhdGFPdXQgPSBkYXRhSW4ubWFwKGQgPT4ge1xuICAgICAgICBjb25zdCB3b3JkSWR4ID0gZC5pbmRleCArIGluZGV4T2Zmc2V0O1xuICAgICAgICBpZiAoKHdvcmRJZHggPCAwKSB8fCAod29yZElkeCA+PSBkLnRva2Vucy5sZW5ndGgpKSB7XG4gICAgICAgICAgICByZXR1cm4gUi5hc3NvYygnaGVpZ2h0JywgZC5oZWlnaHQsIG91dE9mUmFuZ2VPYmopXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdPYmogPSBjaG9vc2VQcm9wcyhkLnRva2Vuc1t3b3JkSWR4XSlcblxuICAgICAgICByZXR1cm4gUi5hc3NvYygnaGVpZ2h0JywgZC5oZWlnaHQsIG5ld09iailcbiAgICB9KVxuXG4gICAgcmV0dXJuIGRhdGFPdXRcbn1cblxuXG5leHBvcnQgY2xhc3MgQ29ycHVzTWF0TWFuYWdlciBleHRlbmRzIFZDb21wb25lbnQ8RGF0YUludGVyZmFjZT57XG4gICAgY3NzX25hbWUgPSAnY29ycHVzLW1hdC1jb250YWluZXInXG4gICAgb3B0aW9ucyA9IHtcbiAgICAgICAgY2VsbFdpZHRoOiAxMCxcbiAgICAgICAgdG9QaWNrOiBbJ3BvcyddLFxuICAgICAgICBpZHhzOiBbLTEsIDAsIDFdLFxuICAgICAgICBkaXZIb3Zlcjoge1xuICAgICAgICAgICAgd2lkdGg6IDYwLFxuICAgICAgICAgICAgaGVpZ2h0OiA0MCBcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBldmVudHMgPSB7XG4gICAgICAgIG1vdXNlT3ZlcjogXCJDb3JwdXNNYXRNYW5hZ2VyX01vdXNlT3ZlclwiLFxuICAgICAgICBtb3VzZU91dDogXCJDb3JwdXNNYXRNYW5hZ2VyX01vdXNlT3V0XCIsXG4gICAgICAgIGNsaWNrOiBcIkNvcnB1c01hdE1hbmFnZXJfQ2xpY2tcIixcbiAgICAgICAgZGJsQ2xpY2s6IFwiQ29ycHVzTWF0TWFuYWdlcl9EYmxDbGlja1wiLFxuICAgICAgICByZWN0TW91c2VPdmVyOiBcIkNvcnB1c01hdE1hbmFnZXJfUmVjdE1vdXNlT3ZlclwiLFxuICAgICAgICByZWN0TW91c2VPdXQ6IFwiQ29ycHVzTWF0TWFuYWdlcl9SZWN0TW91c2VPdXRcIixcbiAgICAgICAgcmVjdENsaWNrOiBcIkNvcnB1c01hdE1hbmFnZXJfUmVjdENsaWNrXCIsXG4gICAgICAgIHJlY3REYmxDbGljazogXCJDb3JwdXNNYXRNYW5hZ2VyX1JlY3REYmxDbGlja1wiLFxuICAgIH1cblxuICAgIC8vIFRoZSBkMyBjb21wb25lbnRzIHRoYXQgYXJlIHNhdmVkIHRvIG1ha2UgcmVuZGVyaW5nIGZhc3RlclxuICAgIGNvcnB1c01hdHM6IEQzU2VsXG4gICAgcm93R3JvdXBzOiBEM1NlbFxuICAgIGRpdkhvdmVyOiBEM1NlbFxuXG4gICAgX2N1cnJlbnQgPSB7fVxuICAgIHJvd0Nzc05hbWUgPSAnaW5kZXgtbWF0Y2gtcmVzdWx0cydcbiAgICBjZWxsQ3NzTmFtZSA9ICdpbmRleC1jZWxsLXJlc3VsdCdcblxuICAgIF9kYXRhOiBEYXRhSW50ZXJmYWNlXG5cbiAgICBzdGF0aWMgY29sb3JTY2FsZTogdHAuQ29sb3JNZXRhU2NhbGUgPSBzcGFjeUNvbG9ycy5jb2xvclNjYWxlO1xuXG4gICAgLy8gU2VsZWN0aW9uc1xuICAgIGNvbnN0cnVjdG9yKGQzcGFyZW50OiBEM1NlbCwgZXZlbnRIYW5kbGVyPzogU2ltcGxlRXZlbnRIYW5kbGVyLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgc3VwZXIoZDNwYXJlbnQsIGV2ZW50SGFuZGxlcilcbiAgICAgICAgdGhpcy5pZHhzID0gWy0xLCAwLCAxXTtcbiAgICAgICAgdGhpcy5zdXBlckluaXRIVE1MKG9wdGlvbnMpXG4gICAgICAgIHRoaXMuX2luaXQoKVxuICAgIH1cblxuICAgIGdldCBpZHhzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmlkeHM7XG4gICAgfVxuXG4gICAgc2V0IGlkeHModmFsOiBudW1iZXJbXSkge1xuICAgICAgICB0aGlzLm9wdGlvbnMuaWR4cyA9IHZhbFxuICAgIH1cblxuICAgIC8vIENyZWF0ZSBzdGF0aWMgZG9tIGVsZW1lbnRzXG4gICAgX2luaXQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLmNvcnB1c01hdHMgPSB0aGlzLmJhc2Uuc2VsZWN0QWxsKCcuY29ycHVzLW1hdCcpXG4gICAgICAgIHRoaXMucm93R3JvdXBzID0gdGhpcy5jb3JwdXNNYXRzLnNlbGVjdEFsbChgLiR7dGhpcy5yb3dDc3NOYW1lfWApXG4gICAgICAgIHRoaXMuZGl2SG92ZXIgPSB0aGlzLmJhc2UuYXBwZW5kKCdkaXYnKVxuICAgICAgICAgICAgLmNsYXNzZWQoJ21hdC1ob3Zlci1kaXNwbGF5JywgdHJ1ZSlcbiAgICAgICAgICAgIC5jbGFzc2VkKCd0ZXh0LWNlbnRlcicsIHRydWUpXG4gICAgICAgICAgICAuc3R5bGUoJ3dpZHRoJywgU3RyaW5nKHRoaXMub3B0aW9ucy5kaXZIb3Zlci53aWR0aCkgKyAncHgnKVxuICAgICAgICAgICAgLnN0eWxlKCdoZWlnaHQnLCBTdHJpbmcodGhpcy5vcHRpb25zLmRpdkhvdmVyLmhlaWdodCkgKyAncHgnKVxuXG4gICAgICAgIHRoaXMuZGl2SG92ZXIuYXBwZW5kKCdwJylcbiAgICB9XG5cbiAgICBwaWNrKHZhbDogRGlzcGxheU9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zLnRvUGljayA9IFt2YWxdXG4gICAgICAgIHRoaXMucmVkcmF3KClcbiAgICB9XG5cbiAgICBhZGRSaWdodCgpIHtcbiAgICAgICAgY29uc3QgYWRkZWRJZHggPSBSLmxhc3QodGhpcy5pZHhzKSArIDE7XG4gICAgICAgIHRoaXMuaWR4cy5wdXNoKGFkZGVkSWR4KVxuICAgICAgICB0aGlzLmFkZENvcnB1c01hdChhZGRlZElkeCwgXCJyaWdodFwiKVxuICAgIH1cblxuICAgIGFkZExlZnQoKSB7XG4gICAgICAgIGNvbnN0IGFkZGVkSWR4ID0gdGhpcy5pZHhzWzBdIC0gMTtcbiAgICAgICAgY29uc3QgYWRkRGVjcmVtZW50ZWRIZWFkOiAoeDogbnVtYmVyW10pID0+IG51bWJlcltdID0geCA9PiBSLmluc2VydCgwLCBSLmhlYWQoeCkgLSAxKSh4KVxuICAgICAgICB0aGlzLmlkeHMgPSBhZGREZWNyZW1lbnRlZEhlYWQodGhpcy5pZHhzKVxuICAgICAgICB0aGlzLmFkZENvcnB1c01hdChhZGRlZElkeCwgXCJsZWZ0XCIpXG4gICAgfVxuXG4gICAga2lsbFJpZ2h0KCkge1xuICAgICAgICB0aGlzLmtpbGwoTWF0aC5tYXgoLi4udGhpcy5pZHhzKSlcbiAgICB9XG5cbiAgICBraWxsTGVmdCgpIHtcbiAgICAgICAgdGhpcy5raWxsKE1hdGgubWluKC4uLnRoaXMuaWR4cykpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGVkZ2UgdmFsdWUgZnJvbSBjb250YWluZWQgaW5kZXhlc1xuICAgICAqXG4gICAgICogQHBhcmFtIGQgSW5kZXggdG8gcmVtb3ZlXG4gICAgICovXG4gICAga2lsbChkOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGQgIT0gMCkge1xuICAgICAgICAgICAgaWYgKGQgPT0gTWF0aC5taW4oLi4udGhpcy5pZHhzKSB8fCBkID09IE1hdGgubWF4KC4uLnRoaXMuaWR4cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlkeHMgPSBSLndpdGhvdXQoW2RdLCB0aGlzLmlkeHMpXG4gICAgICAgICAgICAgICAgdGhpcy5iYXNlLnNlbGVjdEFsbChgLm9mZnNldC0ke2R9YCkucmVtb3ZlKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIF93cmFuZ2xlKGRhdGE6IERhdGFJbnRlcmZhY2UpIHtcbiAgICAgICAgcmV0dXJuIGRhdGFcbiAgICB9XG5cbiAgICBkYXRhKHZhbD86IERhdGFJbnRlcmZhY2UpIHtcbiAgICAgICAgaWYgKHZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2RhdGEgPSB2YWw7XG4gICAgICAgIHRoaXMuX3VwZGF0ZURhdGEoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIG1haW4gcmVuZGVyaW5nIGNvZGUsIGNhbGxlZCB3aGVuZXZlciB0aGUgZGF0YSBjaGFuZ2VzLlxuICAgICAqL1xuICAgIHByaXZhdGUgX3VwZGF0ZURhdGEoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICBjb25zdCBvcCA9IHRoaXMub3B0aW9ucztcblxuICAgICAgICB0aGlzLmJhc2Uuc2VsZWN0QWxsKCcuY29ycHVzLW1hdCcpLnJlbW92ZSgpXG5cbiAgICAgICAgdGhpcy5pZHhzLmZvckVhY2goKGlkeE9mZnNldCwgaSkgPT4ge1xuICAgICAgICAgICAgc2VsZi5hZGRDb3JwdXNNYXQoaWR4T2Zmc2V0KVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCBhbm90aGVyIHdvcmQncyBtZXRhIGluZm9ybWF0aW9uIG1hdHJpeCBjb2x1bW4gdG8gZWl0aGVyIHNpZGUgb2YgdGhlIGluZGV4XG4gICAgICpcbiAgICAgKiBAcGFyYW0gaWR4T2Zmc2V0IERpc3RhbmNlIG9mIHdvcmQgZnJvbSBtYXRjaGVkIHdvcmQgaW4gdGhlIHNlbnRlbmNlXG4gICAgICogQHBhcmFtIHRvVGhlIEluZGljYXRlcyBhZGRpbmcgdG8gdGhlIFwibGVmdFwiIG9yIHRvIHRoZSBcInJpZ2h0XCIgb2YgdGhlIGluZGV4XG4gICAgICovXG4gICAgYWRkQ29ycHVzTWF0KGlkeE9mZnNldDogbnVtYmVyLCB0b1RoZTogXCJyaWdodFwiIHwgXCJsZWZ0XCIgPSBcInJpZ2h0XCIpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBib3hXaWR0aCA9IG9wLmNlbGxXaWR0aCAqIG9wLnRvUGljay5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGJveEhlaWdodCA9IFIuc3VtKFIubWFwKFIucHJvcCgnaGVpZ2h0JyksIHRoaXMuX2RhdGEpKVxuXG4gICAgICAgIGxldCBjb3JwdXNNYXQ7XG5cbiAgICAgICAgaWYgKHRvVGhlID09IFwicmlnaHRcIikge1xuICAgICAgICAgICAgY29ycHVzTWF0ID0gdGhpcy5iYXNlLmFwcGVuZCgnZGl2JylcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0b1RoZSA9PSBcImxlZnRcIikge1xuICAgICAgICAgICAgY29ycHVzTWF0ID0gdGhpcy5iYXNlLmluc2VydCgnZGl2JywgXCI6Zmlyc3QtY2hpbGRcIilcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IEVycm9yKFwidG9UaGUgbXVzdCBoYXZlIGFyZ3VtZW50IG9mICdsZWZ0JyBvciAncmlnaHQnXCIpXG4gICAgICAgIH1cblxuICAgICAgICBjb3JwdXNNYXQgPSBjb3JwdXNNYXRcbiAgICAgICAgICAgIC5kYXRhKFtpZHhPZmZzZXRdKVxuICAgICAgICAgICAgLmF0dHIoJ2NsYXNzJywgYGNvcnB1cy1tYXQgb2Zmc2V0LSR7aWR4T2Zmc2V0fWApXG4gICAgICAgICAgICAuYXR0cignb2Zmc2V0JywgaWR4T2Zmc2V0KVxuICAgICAgICAgICAgLmFwcGVuZCgnc3ZnJylcbiAgICAgICAgICAgIC5hdHRycyh7XG4gICAgICAgICAgICAgICAgd2lkdGg6IGJveFdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogYm94SGVpZ2h0LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5vbignbW91c2VvdmVyJywgZnVuY3Rpb24gKGQsIGkpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmV2ZW50SGFuZGxlci50cmlnZ2VyKENvcnB1c01hdE1hbmFnZXIuZXZlbnRzLm1vdXNlT3ZlciwgeyBpZHg6IGksIG9mZnNldDogZCwgdmFsOiBzZWxmLm9wdGlvbnMudG9QaWNrWzBdIH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKCdtb3VzZW91dCcsIChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIudHJpZ2dlcihDb3JwdXNNYXRNYW5hZ2VyLmV2ZW50cy5tb3VzZU91dCwgeyBpZHg6IGksIG9mZnNldDogZCB9KVxuICAgICAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmFkZFJvd0dyb3VwKGNvcnB1c01hdClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSBtYXQgVGhlIGJhc2UgZGl2IG9uIHdoaWNoIHRvIGFkZCBtYXRyaWNlcyBhbmQgcm93c1xuICAgICAqL1xuICAgIGFkZFJvd0dyb3VwKG1hdDogRDNTZWwpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zO1xuXG4gICAgICAgIGNvbnN0IGhlaWdodHMgPSBSLm1hcChSLnByb3AoJ2hlaWdodCcpLCB0aGlzLl9kYXRhKVxuXG4gICAgICAgIGNvbnN0IFtoZWlnaHRTdW0sIHJhd0hlaWdodExpc3RdID0gUi5tYXBBY2N1bSgoeCwgeSkgPT4gW1IuYWRkKHgsIHkpLCBSLmFkZCh4LCB5KV0sIDAsIGhlaWdodHMpXG4gICAgICAgIGNvbnN0IGZpeExpc3Q6ICh4OiBudW1iZXJbXSkgPT4gbnVtYmVyW10gPSBSLmNvbXBvc2UoUi5kcm9wTGFzdCgxKSxcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIFIucHJlcGVuZCgwKVxuICAgICAgICApXG4gICAgICAgIGNvbnN0IGhlaWdodExpc3QgPSBmaXhMaXN0KHJhd0hlaWdodExpc3QpXG5cbiAgICAgICAgY29uc3Qgcm93R3JvdXAgPSBtYXQuc2VsZWN0QWxsKGAuJHtzZWxmLnJvd0Nzc05hbWV9YClcbiAgICAgICAgICAgIC5kYXRhKGQgPT4gbWFuYWdlckRhdGEyTWF0RGF0YShzZWxmLl9kYXRhLCBkLCBvcC50b1BpY2spKVxuICAgICAgICAgICAgLmpvaW4oXCJnXCIpXG4gICAgICAgICAgICAuYXR0cihcImNsYXNzXCIsIChkLCBpKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGAke3NlbGYucm93Q3NzTmFtZX0gJHtzZWxmLnJvd0Nzc05hbWV9LSR7aX1gXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmF0dHIoXCJyb3ctbnVtXCIsIChkLGkpID0+IGkpXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCBkID0+IGQuaGVpZ2h0KVxuICAgICAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgKGQsIGkpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXQgPSBTVkcudHJhbnNsYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgeDogMCxcbiAgICAgICAgICAgICAgICAgICAgeTogaGVpZ2h0TGlzdFtpXSxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIHJldHVybiBvdXRcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgb3AudG9QaWNrLmZvckVhY2gocHJvcCA9PiB7XG4gICAgICAgICAgICBzZWxmLmFkZFJlY3Qocm93R3JvdXAsIDAsIHByb3ApXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgYWRkUmVjdChnOiBEM1NlbCwgeFNoaWZ0OiBudW1iZXIsIHByb3A6IHN0cmluZykge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpc1xuICAgICAgICBjb25zdCBvcCA9IHRoaXMub3B0aW9uc1xuXG4gICAgICAgIGNvbnN0IHJlY3RzID0gZy5hcHBlbmQoJ3JlY3QnKVxuICAgICAgICAgICAgLmF0dHJzKHtcbiAgICAgICAgICAgICAgICB3aWR0aDogb3AuY2VsbFdpZHRoLFxuICAgICAgICAgICAgICAgIGhlaWdodDogZCA9PiBkLmhlaWdodCAtIDMsXG4gICAgICAgICAgICAgICAgdHJhbnNmb3JtOiAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU1ZHLnRyYW5zbGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgICB4OiB4U2hpZnQsXG4gICAgICAgICAgICAgICAgICAgICAgICB5OiAxLjUsXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuc3R5bGUoJ2ZpbGwnLCBkID0+IENvcnB1c01hdE1hbmFnZXIuY29sb3JTY2FsZVtwcm9wXShkW3Byb3BdKSlcblxuICAgICAgICBcbiAgICAgICAgY29uc3QgZ2V0QmFzZVggPSAoKSA9PiAoPEhUTUxFbGVtZW50PnNlbGYuYmFzZS5ub2RlKCkpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnRcbiAgICAgICAgY29uc3QgZ2V0QmFzZVkgPSAoKSA9PiAoPEhUTUxFbGVtZW50PnNlbGYuYmFzZS5ub2RlKCkpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcFxuXG4gICAgICAgIGcub24oJ21vdXNlb3ZlcicsIGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5kaXZIb3Zlci5zdHlsZSgndmlzaWJpbGl0eScsICd2aXNpYmxlJylcbiAgICAgICAgICAgICAgICAvLyBHZXQgb2Zmc2V0XG4gICAgICAgICAgICAgICAgY29uc3QgY29sID0gZDMuc2VsZWN0KHRoaXMucGFyZW50Tm9kZS5wYXJlbnROb2RlKSAvLyBDb2x1bW5cbiAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSArY29sLmF0dHIoJ29mZnNldCcpXG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihDb3JwdXNNYXRNYW5hZ2VyLmV2ZW50cy5yZWN0TW91c2VPdmVyLCB7aWR4OiBpLCBvZmZzZXQ6IG9mZnNldH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKCdtb3VzZW91dCcsIGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5kaXZIb3Zlci5zdHlsZSgndmlzaWJpbGl0eScsICdoaWRkZW4nKVxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbCA9IGQzLnNlbGVjdCh0aGlzLnBhcmVudE5vZGUucGFyZW50Tm9kZSkgLy8gQ29sdW1uXG4gICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gK2NvbC5hdHRyKCdvZmZzZXQnKVxuICAgICAgICAgICAgICAgIHNlbGYuZXZlbnRIYW5kbGVyLnRyaWdnZXIoQ29ycHVzTWF0TWFuYWdlci5ldmVudHMucmVjdE1vdXNlT3V0LCB7aWR4OiBpLCBvZmZzZXQ6IG9mZnNldH0pXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKCdtb3VzZW1vdmUnLCBmdW5jdGlvbihkLCBpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbW91c2UgPSBkMy5tb3VzZShzZWxmLmJhc2Uubm9kZSgpKVxuICAgICAgICAgICAgICAgIGNvbnN0IGRpdk9mZnNldCA9IFszLCAzXVxuICAgICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBtb3VzZVswXSArIGdldEJhc2VYKCkgLSAob3AuZGl2SG92ZXIud2lkdGggKyBkaXZPZmZzZXRbMF0pXG4gICAgICAgICAgICAgICAgY29uc3QgdG9wID0gbW91c2VbMV0gKyBnZXRCYXNlWSgpIC0gKG9wLmRpdkhvdmVyLmhlaWdodCArIGRpdk9mZnNldFsxXSlcbiAgICAgICAgICAgICAgICBzZWxmLmRpdkhvdmVyXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZSgnbGVmdCcsIFN0cmluZyhsZWZ0KSArICdweCcpXG4gICAgICAgICAgICAgICAgICAgIC5zdHlsZSgndG9wJywgU3RyaW5nKHRvcCkgKyAncHgnKVxuICAgICAgICAgICAgICAgICAgICAuc2VsZWN0QWxsKCdwJylcbiAgICAgICAgICAgICAgICAgICAgLnRleHQoZFtwcm9wXSlcbiAgICAgICAgICAgIH0pXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGRhdGEgRGF0YSB0byBkaXNwbGF5XG4gICAgICovXG4gICAgX3JlbmRlcihkYXRhOiBEYXRhSW50ZXJmYWNlKSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZURhdGEoKTtcbiAgICB9XG5cbn1cbiIsImltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJ1xuaW1wb3J0ICdkMy1hcnJheSdcbmltcG9ydCAqIGFzIGF1IGZyb20gJy4uL2V0Yy9hcnJheVV0aWxzJ1xuaW1wb3J0ICogYXMgdGYgZnJvbSAnQHRlbnNvcmZsb3cvdGZqcydcbmltcG9ydCB7IFR5cGVkQXJyYXkgfSBmcm9tICdAdGVuc29yZmxvdy90ZmpzLWNvcmUvZGlzdC90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWRnZSB7XG4gICAgaTogbnVtYmVyLCAvLyBTb3VyY2UgaW5kZXhcbiAgICBqOiBudW1iZXIsIC8vIFRhcmdldCBpbmRleFxuICAgIHY6IG51bWJlciwgLy8gVmFsdWVcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGRhdGEgbWF0cml4IHRvIG5lY2Vzc2FyeSBkYXRhIGFycmF5IHRvIHBhc3MgdG8gU1ZHIGNvbm5lY3Rpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0VkZ2VzIChkYXRhOm51bWJlcltdW10sIGN1dG9mZkFtdD0xKSA6IEVkZ2VbXSB7XG4gICAgbGV0IG91dEFycjogRWRnZVtdID0gW107XG4gICAgbGV0IGN1dG9mZjogbnVtYmVyO1xuICAgIGRhdGEuZm9yRWFjaCgocm93LCBpKSA9PiB7XG4gICAgICAgIGN1dG9mZiA9IGN1dG9mZkFtdCAqIGQzLnN1bShyb3cpO1xuICAgICAgICBsZXQgY291bnRlciA9IDA7XG4gICAgICAgIGNvbnN0IHNvcnRlZEFycjphdS5Tb3J0QXJyYXkgPSBhdS5zb3J0V2l0aEluZGljZXMocm93KTtcblxuICAgICAgICBzb3J0ZWRBcnIuYXJyLmZvckVhY2goKHYsaikgPT4ge1xuICAgICAgICAgICAgaWYgKGNvdW50ZXIgPCBjdXRvZmYpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvYmo6IEVkZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgIGk6IGksXG4gICAgICAgICAgICAgICAgICAgIGo6IHNvcnRlZEFyci5zb3J0SW5kaWNlc1tqXSxcbiAgICAgICAgICAgICAgICAgICAgdjogdixcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3V0QXJyLnB1c2gob2JqKTtcbiAgICAgICAgICAgICAgICBjb3VudGVyICs9IHY7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KVxuXG4gICAgcmV0dXJuIG91dEFycjtcbn1cbi8qKlxuICogQ2xhc3MgZm9yIGltcGxlbWVudGluZyBvcGVyYXRpb25zIG9uIEF0dGVudGlvbkdyYXBoIGltcGxlbWVudGF0aW9uLiBcbiAqIENsb3NlbHkgdGllZCB0byBbW0F0dGVudGlvbkNvbm5lY3Rvcl1dXG4gKi9cbmV4cG9ydCBjbGFzcyBFZGdlRGF0YSB7XG4gICAgcmVhZG9ubHkgdGVuc0RhdGE6dGYuVGVuc29yO1xuXG4gICAgY29uc3RydWN0b3IgKHB1YmxpYyBkYXRhOm51bWJlcltdW10pe1xuICAgICAgICB0aGlzLnRlbnNEYXRhID0gdGYudGVuc29yKGRhdGEpO1xuICAgIH1cblxuICAgIG1pbihheGlzPzpudW1iZXIpOlR5cGVkQXJyYXkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZW5zRGF0YS5taW4oYXhpcykuZGF0YVN5bmMoKTtcbiAgICB9XG5cbiAgICBtYXgoYXhpcz86bnVtYmVyKTpUeXBlZEFycmF5e1xuICAgICAgICByZXR1cm4gdGhpcy50ZW5zRGF0YS5tYXgoYXhpcykuZGF0YVN5bmMoKTtcbiAgICB9XG5cbiAgICBleHRlbnQoYXhpcz86bnVtYmVyKTpudW1iZXJbXVtdIHtcbiAgICAgICAgcmV0dXJuIGQzLnppcCh0aGlzLm1pbihheGlzKSwgdGhpcy5tYXgoYXhpcykpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IHRoZSBkYXRhIHRvIHNlbmQgdG8gU1ZHIGNoYXJ0LlxuICAgICAqIFxuICAgICAqIEBwYXJhbSBhY2N1bXVsYXRlVGhyZXNoIC0gQSBmbG9hdCBiZXR3ZWVuIDAgYW5kIDEsIGluZGljYXRpbmcgdGhlIGFtb3VudCBvZiB3ZWlnaHQgdG8gZGlzcGxheS4gRGVmYXVsdHMgdG8gMC43LlxuICAgICAqL1xuICAgIGZvcm1hdCAoYWNjdW11bGF0ZVRocmVzaD0wLjcpOkVkZ2VbXSB7XG4gICAgICAgIHJldHVybiB0b0VkZ2VzKHRoaXMuZGF0YSwgYWNjdW11bGF0ZVRocmVzaCk7XG4gICAgfVxufSIsImltcG9ydCAqIGFzIGQzIGZyb20gXCJkM1wiO1xuaW1wb3J0ICogYXMgUiBmcm9tIFwicmFtZGFcIlxuaW1wb3J0ICogYXMgXyBmcm9tIFwibG9kYXNoXCJcbmltcG9ydCB7IFZDb21wb25lbnQgfSBmcm9tIFwiLi9WaXNDb21wb25lbnRcIjtcbmltcG9ydCB7IFNpbXBsZUV2ZW50SGFuZGxlciB9IGZyb20gXCIuLi9ldGMvU2ltcGxlRXZlbnRIYW5kbGVyXCI7XG5pbXBvcnQgeyBEM1NlbCB9IGZyb20gXCIuLi9ldGMvVXRpbFwiO1xuaW1wb3J0ICogYXMgdHAgZnJvbSBcIi4uL2V0Yy90eXBlc1wiXG5cbnR5cGUgaW5mb0V2ZW50RnJvbUkgPSAoc2VsOiBEM1NlbCwgaTogbnVtYmVyKSA9PiB0cC5Ub2tlbkV2ZW50XG50eXBlIGluZm9FbWJlZGRpbmdFdmVudEZyb21JID0gKHNlbDogRDNTZWwsIGk6IG51bWJlciwgZW1iZWQ6IG51bWJlcltdKSA9PiB0cC5Ub2tlbkVtYmVkZGluZ0V2ZW50XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUZXh0VG9rZW5zIGV4dGVuZHMgVkNvbXBvbmVudDx0cC5GdWxsU2luZ2xlVG9rZW5JbmZvW10+e1xuXG4gICAgYWJzdHJhY3QgY3NzX25hbWU6IHN0cmluZ1xuICAgIGFic3RyYWN0IGhvdmVyX2Nzc19uYW1lOiBzdHJpbmdcbiAgICBhYnN0cmFjdCBzaWRlOiB0cC5TaWRlT3B0aW9uc1xuICAgIGVJbmZvOiBpbmZvRXZlbnRGcm9tSSA9IChzZWwsIGkpID0+IHsgcmV0dXJuIHsgc2VsOiBzZWwsIHNpZGU6IHRoaXMuc2lkZSwgaW5kOiBpIH0gfVxuICAgIGVFbWJlZGRpbmc6IGluZm9FbWJlZGRpbmdFdmVudEZyb21JID0gKHNlbCwgaSwgZW1iZWQpID0+IHsgcmV0dXJuIHsgc2VsOiBzZWwsIHNpZGU6IHRoaXMuc2lkZSwgaW5kOiBpLCBlbWJlZGRpbmdzOiBlbWJlZCB9IH1cbiAgICBkaXZIb3ZlcjogRDNTZWxcblxuICAgIHN0YXRpYyBldmVudHMgPSB7XG4gICAgICAgIHRva2VuTW91c2VPdmVyOiBcIlRleHRUb2tlbl9Ub2tlbk1vdXNlT3ZlclwiLFxuICAgICAgICB0b2tlbk1vdXNlT3V0OiBcIlRleHRUb2tlbl9Ub2tlbk1vdXNlT3V0XCIsXG4gICAgICAgIHRva2VuQ2xpY2s6IFwiVGV4dFRva2VuX1Rva2VuQ2xpY2tcIixcbiAgICAgICAgdG9rZW5EYmxDbGljazogXCJUZXh0VG9rZW5fVG9rZW5EYmxDbGlja1wiLFxuICAgIH07XG5cbiAgICBkYXRhOiB0cC5GdWxsU2luZ2xlVG9rZW5JbmZvW107XG5cbiAgICBfY3VycmVudDoge307XG5cbiAgICBvcHRpb25zID0ge1xuICAgICAgICBib3hoZWlnaHQ6IDI2LFxuICAgICAgICBvZmZzZXQ6IDAsXG4gICAgICAgIGRpdkhvdmVyOiB7XG4gICAgICAgICAgICB3aWR0aDogMTUwLFxuICAgICAgICAgICAgaGVpZ2h0OiAxNTAsXG4gICAgICAgICAgICBvZmZzZXQ6IFszLCAzXSxcbiAgICAgICAgICAgIHRleHRJbmZvOiBcIldvdWxkIHByZWRpY3QuLi5cIlxuICAgICAgICB9LFxuICAgIH07XG5cbiAgICB0ZXh0Qm94ZXM6IEQzU2VsXG5cbiAgICBjb25zdHJ1Y3RvcihkM1BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86IFNpbXBsZUV2ZW50SGFuZGxlciwgb3B0aW9uczoge30gPSB7fSkge1xuICAgICAgICBzdXBlcihkM1BhcmVudCwgZXZlbnRIYW5kbGVyKTtcbiAgICAgICAgdGhpcy5zdXBlckluaXRIVE1MKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIG1hc2sobWFza0luZHM6IG51bWJlcltdKSB7XG4gICAgICAgIHRoaXMucGFyZW50LnNlbGVjdEFsbChgLiR7dGhpcy5jc3NfbmFtZX1gKVxuICAgICAgICAgICAgLmVhY2goKGQsIGksIG4pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWwgPSBkMy5zZWxlY3QobltpXSlcbiAgICAgICAgICAgICAgICBzZWwuY2xhc3NlZChcIm1hc2tlZC10b2tlblwiLCBfLmluY2x1ZGVzKG1hc2tJbmRzLCBpKSlcbiAgICAgICAgICAgIH0pXG4gICAgfVxuXG4gICAgZ2V0RW1iZWRkaW5nKGluZDogbnVtYmVyKTogdHAuRnVsbFNpbmdsZVRva2VuSW5mbyB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhW2luZF1cbiAgICB9XG5cbiAgICBfaW5pdCgpIHsgfVxuXG4gICAgX3dyYW5nbGUoZGF0YTogdHAuRnVsbFNpbmdsZVRva2VuSW5mb1tdKSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IHRoaXMuX2RhdGE7XG4gICAgICAgIHJldHVybiB0aGlzLl9kYXRhO1xuICAgIH1cblxuICAgIF9kaXZQbGFjZW1lbnQoKSB7XG4gICAgICAgIGNvbnN0IGdldEJhc2VYID0gKCkgPT4gKDxIVE1MRWxlbWVudD5zZWxmLmJhc2Uubm9kZSgpKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0XG4gICAgICAgIGNvbnN0IGdldEJhc2VZID0gKCkgPT4gKDxIVE1MRWxlbWVudD5zZWxmLmJhc2Uubm9kZSgpKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3BcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXNcbiAgICAgICAgY29uc3Qgb3AgPSB0aGlzLm9wdGlvbnNcbiAgICAgICAgY29uc3QgbW91c2UgPSBkMy5tb3VzZShzZWxmLmJhc2Uubm9kZSgpKVxuICAgICAgICBjb25zdCBkaXZPZmZzZXQgPSBbMywgM11cbiAgICAgICAgY29uc3QgbGVmdCA9IG1vdXNlWzBdICsgZ2V0QmFzZVgoKSAtIChvcC5kaXZIb3Zlci53aWR0aCArIGRpdk9mZnNldFswXSlcbiAgICAgICAgY29uc3QgdG9wID0gbW91c2VbMV0gKyBnZXRCYXNlWSgpICsgZGl2T2Zmc2V0WzFdXG4gICAgICAgIHJldHVybiBbbGVmdCwgdG9wXVxuICAgIH1cblxuICAgIF9yZW5kZXIoZGF0YTogdHAuRnVsbFNpbmdsZVRva2VuSW5mb1tdKSB7XG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zO1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgLy8gUmVzZXQgdG9rZW4gZGlzcGxheVxuICAgICAgICB0aGlzLmJhc2Uuc2VsZWN0QWxsKFwiKlwiKS5yZW1vdmUoKVxuXG4gICAgICAgIHRoaXMuZGl2SG92ZXIgPSB0aGlzLmJhc2UuYXBwZW5kKCdkaXYnKVxuICAgICAgICAgICAgLmNsYXNzZWQoJ3Rvay1pbmZvJywgdHJ1ZSlcbiAgICAgICAgICAgIC5jbGFzc2VkKCdtYXQtaG92ZXItZGlzcGxheScsIHRydWUpXG4gICAgICAgICAgICAuY2xhc3NlZCh0aGlzLmhvdmVyX2Nzc19uYW1lLCB0cnVlKVxuICAgICAgICAgICAgLnN0eWxlKCd3aWR0aCcsIFN0cmluZyh0aGlzLm9wdGlvbnMuZGl2SG92ZXIud2lkdGgpICsgJ3B4JylcbiAgICAgICAgICAgIC5zdHlsZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMub3B0aW9ucy5kaXZIb3Zlci5oZWlnaHQpICsgJ3B4JylcblxuICAgICAgICB0aGlzLmRpdkhvdmVyXG4gICAgICAgICAgICAuYXBwZW5kKCdwJylcbiAgICAgICAgICAgIC5jbGFzc2VkKCdwLWluZm8nLCB0cnVlKVxuICAgICAgICAgICAgLnN0eWxlKCdmb250LXdlaWdodCcsICdib2xkJylcbiAgICAgICAgICAgIC50ZXh0KG9wLmRpdkhvdmVyLnRleHRJbmZvKVxuXG5cbiAgICAgICAgLy8gQWRkIGJsYW5rIGRpdnNcbiAgICAgICAgY29uc29sZS5sb2coYEludGVybmFsIG9mZnNldCAoJHt0aGlzLnNpZGV9KTogYCwgb3Aub2Zmc2V0KTtcbiAgICAgICAgY29uc3QgYmxhbmtEaXZzID0gdGhpcy5iYXNlLnNlbGVjdEFsbChgLmJsYW5rLXRleHQtYm94YClcblxuICAgICAgICBibGFua0RpdnMuZGF0YShSLnJhbmdlKDAsIG9wLm9mZnNldCkpXG4gICAgICAgICAgICAuam9pbihcImRpdlwiKVxuICAgICAgICAgICAgLmNsYXNzZWQoXCJibGFuay10ZXh0LWJveFwiLCB0cnVlKVxuICAgICAgICAgICAgLmNsYXNzZWQoXCJ0b2tlblwiLCB0cnVlKVxuICAgICAgICAgICAgLnN0eWxlKFwiaGVpZ2h0XCIsIG9wLmJveGhlaWdodCArICdweCcpXG4gICAgICAgICAgICAudGV4dCgoZCkgPT4gXCIgIFwiKVxuXG4gICAgICAgIC8vIFJlbmRlciBub3JtYWwgdGV4dCBib3ggZGF0YVxuICAgICAgICBzZWxmLnRleHRCb3hlcyA9IDxEM1NlbD50aGlzLmJhc2Uuc2VsZWN0QWxsKGAuJHt0aGlzLmNzc19uYW1lfWApXG4gICAgICAgICAgICAuZGF0YShkYXRhKVxuICAgICAgICAgICAgLmpvaW4oXCJkaXZcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgKGQsIGkpID0+IGB0b2tlbiAke3RoaXMuY3NzX25hbWV9IHRva2VuLSR7aX1gKVxuICAgICAgICAgICAgLmF0dHIoXCJpZFwiLCAoZCwgaSkgPT4gYCR7dGhpcy5jc3NfbmFtZX0tJHtpfWApXG4gICAgICAgICAgICAuc3R5bGUoJ2hlaWdodCcsIG9wLmJveGhlaWdodCArICdweCcpXG4gICAgICAgICAgICAudGV4dCgoZCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkLnRleHQucmVwbGFjZShcIlxcdTAxMjBcIiwgXCIgXCIpLnJlcGxhY2UoXCJcXHUwMTBBXCIsIFwiXFxcXG5cIilcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oJ21vdXNlb3ZlcicsIGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsID0gZDMuc2VsZWN0KHRoaXMpO1xuICAgICAgICAgICAgICAgIHNlbC5zdHlsZSgnYmFja2dyb3VuZCcsICdsaWdodGJsdWUnKTtcbiAgICAgICAgICAgICAgICBzZWxmLmV2ZW50SGFuZGxlci50cmlnZ2VyKFRleHRUb2tlbnMuZXZlbnRzLnRva2VuTW91c2VPdmVyLCBzZWxmLmVJbmZvKHNlbCwgaSkpXG4gICAgICAgICAgICAgICAgc2VsZi5kaXZIb3Zlci5zdHlsZSgndmlzaWJpbGl0eScsICd2aXNpYmxlJylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oJ21vdXNlb3V0JywgZnVuY3Rpb24gKGQsIGkpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2VsID0gZDMuc2VsZWN0KHRoaXMpO1xuICAgICAgICAgICAgICAgIHNlbC5zdHlsZSgnYmFja2dyb3VuZCcsIDApXG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihUZXh0VG9rZW5zLmV2ZW50cy50b2tlbk1vdXNlT3V0LCBzZWxmLmVJbmZvKHNlbCwgaSkpXG4gICAgICAgICAgICAgICAgc2VsZi5kaXZIb3Zlci5zdHlsZSgndmlzaWJpbGl0eScsICdoaWRkZW4nKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5vbignbW91c2Vtb3ZlJywgZnVuY3Rpb24gKGQsIGkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzID0gZDMuc2VsZWN0KHRoaXMpXG4gICAgICAgICAgICAgICAgY29uc3QgW2xlZnQsIHRvcF0gPSBzZWxmLl9kaXZQbGFjZW1lbnQoKVxuXG4gICAgICAgICAgICAgICAgc2VsZi5kaXZIb3ZlclxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoJ2xlZnQnLCBTdHJpbmcobGVmdCkgKyAncHgnKVxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoJ3RvcCcsIFN0cmluZyh0b3ApICsgJ3B4JylcbiAgICAgICAgICAgICAgICAgICAgLnNlbGVjdEFsbChcIi50b3BrLXdvcmQtYm94XCIpXG4gICAgICAgICAgICAgICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICAuZGF0YShkMy56aXAoZC50b3BrX3dvcmRzLCBkLnRvcGtfcHJvYnMpKVxuICAgICAgICAgICAgICAgICAgICAuam9pbigncCcpXG4gICAgICAgICAgICAgICAgICAgIC5jbGFzc2VkKFwidG9way13b3JkLWJveFwiLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICAudGV4dCh3ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB3WzBdLnJlcGxhY2UoL1xcdTAxMjAvZywgXCIgXCIpLnJlcGxhY2UoL1xcdTAxMEEvZywgXCJcXFxcblwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvYiA9IHdbMV0udG9GaXhlZCgyKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hbWUgKyBcIjogXCIgKyBwcm9iXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgIHNlbGYuYWRkQ2xpY2soc2VsZi50ZXh0Qm94ZXMpXG4gICAgfVxuXG4gICAgYWRkQ2xpY2sodGV4dGJveGVzOiBEM1NlbCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgICAgICBzZWxmLnRleHRCb3hlcyA9IHRleHRib3hlc1xuICAgICAgICAgICAgLm9uKCdjbGljaycsIChkLCBpLCBuKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsID0gZDMuc2VsZWN0KG5baV0pO1xuICAgICAgICAgICAgICAgIHNlbGYuZXZlbnRIYW5kbGVyLnRyaWdnZXIoVGV4dFRva2Vucy5ldmVudHMudG9rZW5DbGljaywgc2VsZi5lRW1iZWRkaW5nKHNlbCwgaSwgZC5lbWJlZGRpbmdzKSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oJ2RibGNsaWNrJywgKGQsIGksIG4pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWwgPSBkMy5zZWxlY3QobltpXSk7XG4gICAgICAgICAgICAgICAgc2VsZi5ldmVudEhhbmRsZXIudHJpZ2dlcihUZXh0VG9rZW5zLmV2ZW50cy50b2tlbkRibENsaWNrLCBzZWxmLmVJbmZvKHNlbCwgaSkpXG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMZWZ0VGV4dFRva2VuIGV4dGVuZHMgVGV4dFRva2VucyB7XG5cbiAgICBjc3NfbmFtZSA9ICdsZWZ0LXRva2VuJztcbiAgICBob3Zlcl9jc3NfbmFtZSA9ICdsZWZ0LXRva2VuLWhvdmVyJ1xuICAgIHNpZGU6IHRwLlNpZGVPcHRpb25zID0gJ2xlZnQnO1xuICAgIG9mZnNldDogbnVtYmVyID0gMTtcblxuICAgIGNvbnN0cnVjdG9yKGQzUGFyZW50OiBEM1NlbCwgZXZlbnRIYW5kbGVyPzogU2ltcGxlRXZlbnRIYW5kbGVyLCBvcHRpb25zOiB7fSA9IHt9KSB7XG4gICAgICAgIHN1cGVyKGQzUGFyZW50LCBldmVudEhhbmRsZXIpO1xuICAgIH1cblxuXG59XG5cbmV4cG9ydCBjbGFzcyBSaWdodFRleHRUb2tlbiBleHRlbmRzIFRleHRUb2tlbnMge1xuICAgIGNzc19uYW1lID0gJ3JpZ2h0LXRva2VuJztcbiAgICBob3Zlcl9jc3NfbmFtZSA9ICdyaWdodC10b2tlbi1ob3ZlcidcbiAgICBzaWRlOiB0cC5TaWRlT3B0aW9ucyA9ICdyaWdodCdcbiAgICBvZmZzZXQ6IG51bWJlciA9IDA7XG5cbiAgICBjb25zdHJ1Y3RvcihkM1BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86IFNpbXBsZUV2ZW50SGFuZGxlciwgb3B0aW9uczoge30gPSB7fSkge1xuICAgICAgICBzdXBlcihkM1BhcmVudCwgZXZlbnRIYW5kbGVyKTtcbiAgICB9XG5cbiAgICBfZGl2UGxhY2VtZW50KCkge1xuICAgICAgICBjb25zdCBnZXRCYXNlWCA9ICgpID0+ICg8SFRNTEVsZW1lbnQ+c2VsZi5iYXNlLm5vZGUoKSkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdFxuICAgICAgICBjb25zdCBnZXRCYXNlWSA9ICgpID0+ICg8SFRNTEVsZW1lbnQ+c2VsZi5iYXNlLm5vZGUoKSkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wXG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzXG4gICAgICAgIGNvbnN0IG9wID0gdGhpcy5vcHRpb25zXG4gICAgICAgIGNvbnN0IG1vdXNlID0gZDMubW91c2Uoc2VsZi5iYXNlLm5vZGUoKSlcbiAgICAgICAgY29uc3QgZGl2T2Zmc2V0ID0gWzMsIDNdXG4gICAgICAgIGNvbnN0IGxlZnQgPSBtb3VzZVswXSArIGdldEJhc2VYKCkgKyBkaXZPZmZzZXRbMF1cbiAgICAgICAgY29uc3QgdG9wID0gbW91c2VbMV0gKyBnZXRCYXNlWSgpICsgZGl2T2Zmc2V0WzFdXG4gICAgICAgIHJldHVybiBbbGVmdCwgdG9wXVxuICAgIH1cbn1cbiIsIi8qKlxuICogQ3JlYXRlZCBieSBIZW5kcmlrIFN0cm9iZWx0IChoZW5kcmlrLnN0cm9iZWx0LmNvbSkgb24gMTIvMy8xNi5cbiAqIE1vZGlmaWVkIGJ5IEJlbiBIb292ZXIgb24gNC8xNi8yMDE5XG4gKi9cbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJ1xuaW1wb3J0IHtEM1NlbCwgVXRpbH0gZnJvbSBcIi4uL2V0Yy9VdGlsXCI7XG5pbXBvcnQge1NpbXBsZUV2ZW50SGFuZGxlcn0gZnJvbSBcIi4uL2V0Yy9TaW1wbGVFdmVudEhhbmRsZXJcIjtcbmltcG9ydCB7U1ZHfSBmcm9tIFwiLi4vZXRjL1NWR3BsdXNcIjtcblxuLyoqXG4gKiBTaG91bGQgaGF2ZSBWQ29tcG9uZW50SFRNTCBhbmQgVkNvbXBvbmVudFNWR1xuICogXG4gKiBDb21tb24gUHJvcGVydGllczpcbiAqIC0gZXZlbnRzXG4gKiAtIGV2ZW50SGFuZGxlciAoViBpbXBvcnRhbnQpXG4gKiAtIG9wdGlvbnMgKE1haW50YWlucyBwdWJsaWMgc3RhdGUuIENhbiBleHBvc2UgdGhlc2Ugd2l0aCBnZXQvc2V0IGZ1bmN0aW9ucyB3aXRoIGF1dG8gdXBkYXRlKVxuICogLSBfY3VycmVudCAoTWFpbnRhaW5zIHByaXZhdGUgc3RhdGUpXG4gKiAtIGNzc05hbWUgKHN5bmNlZCB3aXRoIGNvcnJlc3BvbmRpbmcgQ1NTIGZpbGUpXG4gKiAtIHBhcmVudCAoSFRNTCBpcyBkaXYgY29udGFpbmluZyB0aGUgYmFzZSwgU1ZHIGlzIFNWRyBlbGVtZW50KVxuICogLSBiYXNlIChIVE1MIGlzIGRpdiB3aXRoIGNzc19uYW1lIGVzdGFibGlzaGVkKVxuICogLSBfZGF0YSAoRGF0YSB1c2VkIHRvIGNyZWF0ZSBhbmQgcmVuZGVyIHRoZSBjb21wb25lbnQpXG4gKiAtIF9yZW5kZXJEYXRhIChEYXRhIG5lZWRlZCB0byBkaXNwbGF5LiBUaGlzIG1heSBub3QgYmUgbmVlZGVkLCBidXQgaXMgY3VycmVudGx5IHVzZWQgaW4gaGlzdG9ncmFtKVxuICogXG4gKiBDb21tb24gTWV0aG9kczpcbiAqIC0gY29uc3RydWN0b3JcbiAqIC0gX3JlbmRlcigpICAgICAgQ29uc2lkZXIgcmVwbGFjaW5nIHdpdGggYF91cGRhdGVEYXRhKClgIHRoYXQgdXBkYXRlcyBhbGwgZGF0YSBhdCBvbmNlXG4gKiAtIHVwZGF0ZSgpICAgICAgIENvbnNpZGVyIHJlcGxhY2luZyB0aGlzIHdpdGggYGRhdGEoKWAgdGhhdCBhdXRvIHVwZGF0ZXMgZGF0YVxuICogLSByZWRyYXcoKVxuICogLSBkZXN0cm95KClcbiAqL1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVkNvbXBvbmVudDxEYXRhSW50ZXJmYWNlPiB7XG5cbiAgICAvLyBTVEFUSUMgRklFTERTID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRpYyBwcm9wZXJ0eSB0aGF0IGNvbnRhaW5zIGFsbCBjbGFzcyByZWxhdGVkIGV2ZW50cy5cbiAgICAgKiBTaG91bGQgYmUgb3ZlcndyaXR0ZW4gYW5kIGV2ZW50IHN0cmluZ3MgaGF2ZSB0byBiZSB1bmlxdWUhIVxuICAgICAqL1xuXG4gICAgc3RhdGljIGV2ZW50czoge30gPSB7bm9FdmVudDogJ1ZDb21wb25lbnRfbm9FdmVudCd9O1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyB0aGUgbGF5ZXJzIGluIFNWRyAgZm9yIGJnLG1haW4sZmcsLi4uXG4gICAgICovXG4gICAgLy8gcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IGxheW91dDogeyBuYW1lOiBzdHJpbmcsIHBvczogbnVtYmVyW10gfVtdID0gW3tuYW1lOiAnbWFpbicsIHBvczogWzAsIDBdfV07XG5cbiAgICBwcm90ZWN0ZWQgaWQ6IHN0cmluZzsgLy8gTW9zdGx5IG9ic29sZXRlLCBuaWNlIHRvIGhhdmUgc2ltcGxlIElEIHRvIGFzc2lnbiBpbiBDU1NcbiAgICBwcm90ZWN0ZWQgcGFyZW50OiBEM1NlbDtcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3Qgb3B0aW9uczogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbiAgICBwcm90ZWN0ZWQgYmFzZTogRDNTZWw7IC8vIE1vc3RseSBvYnNvbGV0ZSwgcmVwcmVzZW50cyA8Zz4gaW4gc3ZnXG4gICAgcHJvdGVjdGVkIGxheWVyczogeyBtYWluPzogRDNTZWwsIGZnPzogRDNTZWwsIGJnPzogRDNTZWwsIFtrZXk6IHN0cmluZ106IEQzU2VsIH07IC8vIFN0aWxsIHVzZWZ1bFxuICAgIHByb3RlY3RlZCBldmVudEhhbmRsZXI6IFNpbXBsZUV2ZW50SGFuZGxlcjtcbiAgICBwcm90ZWN0ZWQgX3Zpc2liaWxpdHk6IHsgaGlkZGVuOiBib29sZWFuLCBoaWRlRWxlbWVudD86IEQzU2VsIHwgbnVsbDsgW2tleTogc3RyaW5nXTogYW55IH07IC8vIEVuYWJsZXMgdHJhbnNpdGlvbnMgZnJvbSB2aXNpYmxlIHRvIGludmlzaWJsZS4gTW9zdGx5IG9ic29sZXRlLlxuICAgIHByb3RlY3RlZCBfZGF0YTogRGF0YUludGVyZmFjZTtcbiAgICBwcm90ZWN0ZWQgcmVuZGVyRGF0YTogYW55OyAvLyBVbm5lY2Vzc2FyeVxuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBjc3NfbmFtZTogc3RyaW5nOyAvLyBNYWtlIHRoZSBzYW1lIGFzIHRoZSBjb3JyZXNwb25kaW5nIGNzcyBmaWxlXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IF9jdXJyZW50OiB7fTsgLy8gUHJpdmF0ZSBzdGF0ZSBpbmZvcm1hdGlvbiBjb250YWluZWQgaW4gdGhlIG9iamVjdCBpdHNlbGYuXG5cbiAgICAvLyBDT05TVFJVQ1RPUiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIFNpbXBsZSBjb25zdHJ1Y3Rvci4gU3ViY2xhc3NlcyBzaG91bGQgY2FsbCBAc3VwZXJJbml0KG9wdGlvbnMpIGFzIHdlbGwuXG4gICAgICogc2VlIHdoeSBoZXJlOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MzU5NTk0My93aHktYXJlLWRlcml2ZWQtY2xhc3MtcHJvcGVydHktdmFsdWVzLW5vdC1zZWVuLWluLXRoZS1iYXNlLWNsYXNzLWNvbnN0cnVjdG9yXG4gICAgICpcbiAgICAgKiB0ZW1wbGF0ZTpcbiAgICAgY29uc3RydWN0b3IoZDNQYXJlbnQ6IEQzU2VsLCBldmVudEhhbmRsZXI/OiBTaW1wbGVFdmVudEhhbmRsZXIsIG9wdGlvbnM6IHt9ID0ge30pIHtcbiAgICAgICAgc3VwZXIoZDNQYXJlbnQsIGV2ZW50SGFuZGxlcik7XG4gICAgICAgIC8vIC0tIGFjY2VzcyB0byBzdWJjbGFzcyBwYXJhbXM6XG4gICAgICAgIHRoaXMuc3VwZXJJbml0KG9wdGlvbnMpO1xuICAgICB9XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0QzU2VsfSBkM3BhcmVudCAgRDMgc2VsZWN0aW9uIG9mIHBhcmVudCBTVkcgRE9NIEVsZW1lbnRcbiAgICAgKiBAcGFyYW0ge1NpbXBsZUV2ZW50SGFuZGxlcn0gZXZlbnRIYW5kbGVyIGEgZ2xvYmFsIGV2ZW50IGhhbmRsZXIgb2JqZWN0IG9yICdudWxsJyBmb3IgbG9jYWwgZXZlbnQgaGFuZGxlclxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihkM3BhcmVudDogRDNTZWwsIGV2ZW50SGFuZGxlcj86IFNpbXBsZUV2ZW50SGFuZGxlcikge1xuICAgICAgICB0aGlzLmlkID0gVXRpbC5zaW1wbGVVSWQoe30pO1xuXG4gICAgICAgIHRoaXMucGFyZW50ID0gZDNwYXJlbnQ7XG5cbiAgICAgICAgLy8gSWYgbm90IGZ1cnRoZXIgc3BlY2lmaWVkIC0gY3JlYXRlIGEgbG9jYWwgZXZlbnQgaGFuZGxlciBib3VuZCB0byB0aGUgYmFzIGVsZW1lbnRcbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIgPSBldmVudEhhbmRsZXIgfHxcbiAgICAgICAgICAgIG5ldyBTaW1wbGVFdmVudEhhbmRsZXIodGhpcy5wYXJlbnQubm9kZSgpKTtcblxuICAgICAgICAvLyBPYmplY3QgZm9yIHN0b3JpbmcgaW50ZXJuYWwgc3RhdGVzIGFuZCB2YXJpYWJsZXNcbiAgICAgICAgdGhpcy5fdmlzaWJpbGl0eSA9IHtoaWRkZW46IGZhbHNlfTtcblxuICAgIH1cblxuICAgIHByb3RlY3RlZCBzdXBlckluaXRIVE1MKG9wdGlvbnM6IHt9ID0ge30pIHtcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChrZXkgPT4gdGhpcy5vcHRpb25zW2tleV0gPSBvcHRpb25zW2tleV0pO1xuICAgICAgICB0aGlzLmJhc2UgPSB0aGlzLnBhcmVudC5hcHBlbmQoJ2RpdicpXG4gICAgICAgICAgICAuY2xhc3NlZCh0aGlzLmNzc19uYW1lLCB0cnVlKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhcyB0byBiZSBjYWxsZWQgYXMgbGFzdCBjYWxsIGluIHN1YmNsYXNzIGNvbnN0cnVjdG9yLlxuICAgICAqIFxuICAgICAqIEBwYXJhbSB7e319IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gZGVmYXVsdExheWVycyAtLSBjcmVhdGUgdGhlIGRlZmF1bHQgPGc+IGxheWVyczogYmcgLT4gbWFpbiAtPiBmZ1xuICAgICAqL1xuICAgIHByb3RlY3RlZCBzdXBlckluaXRTVkcob3B0aW9uczoge30gPSB7fSwgZGVmYXVsdExheWVycyA9IFsnYmcnLCAnbWFpbicsICdmZyddKSB7XG4gICAgICAgIC8vIFNldCBkZWZhdWx0IG9wdGlvbnMgaWYgbm90IHNwZWNpZmllZCBpbiBjb25zdHJ1Y3RvciBjYWxsXG4gICAgICAgIC8vIGNvbnN0IGRlZmF1bHRzID0gdGhpcy5kZWZhdWx0T3B0aW9ucztcbiAgICAgICAgLy8gdGhpcy5vcHRpb25zID0ge307XG4gICAgICAgIC8vIGNvbnN0IGtleXMgPSBuZXcgU2V0KFsuLi5PYmplY3Qua2V5cyhkZWZhdWx0cyksIC4uLk9iamVjdC5rZXlzKG9wdGlvbnMpXSk7XG4gICAgICAgIC8vIGtleXMuZm9yRWFjaChrZXkgPT4gdGhpcy5vcHRpb25zW2tleV0gPSAoa2V5IGluIG9wdGlvbnMpID8gb3B0aW9uc1trZXldIDogZGVmYXVsdHNba2V5XSk7XG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2goa2V5ID0+IHRoaXMub3B0aW9uc1trZXldID0gb3B0aW9uc1trZXldKTtcblxuICAgICAgICB0aGlzLmxheWVycyA9IHt9O1xuXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgYmFzZSBncm91cCBlbGVtZW50XG4gICAgICAgIGNvbnN0IHN2ZyA9IHRoaXMucGFyZW50O1xuICAgICAgICB0aGlzLmJhc2UgPSBTVkcuZ3JvdXAoc3ZnLFxuICAgICAgICAgICAgdGhpcy5jc3NfbmFtZSArICcgSUQnICsgdGhpcy5pZCxcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucy5wb3MpO1xuXG4gICAgICAgIC8vIGNyZWF0ZSBkZWZhdWx0IGxheWVyczogYmFja2dyb3VuZCwgbWFpbiwgZm9yZWdyb3VuZFxuICAgICAgICBpZiAoZGVmYXVsdExheWVycykge1xuICAgICAgICAgICAgLy8gY29uc3RydWN0aW9uIG9yZGVyIGlzIGltcG9ydGFudCAhXG4gICAgICAgICAgICBkZWZhdWx0TGF5ZXJzLmZvckVhY2gobGF5ZXIgPT57XG4gICAgICAgICAgICAgICAgdGhpcy5sYXllcnNbbGF5ZXJdID0gU1ZHLmdyb3VwKHRoaXMuYmFzZSwgbGF5ZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAqIFNob3VsZCBiZSBvdmVyd3JpdHRlbiB0byBjcmVhdGUgdGhlIHN0YXRpYyBET00gZWxlbWVudHNcbiAgICAgKiBAYWJzdHJhY3RcbiAgICAgKiBAcmV0dXJuIHsqfSAtLS1cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgX2luaXQoKTtcblxuICAgIC8vIERBVEEgVVBEQVRFICYgUkVOREVSID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogRXZlcnkgdGltZSBkYXRhIGhhcyBjaGFuZ2VkLCB1cGRhdGUgaXMgY2FsbGVkIGFuZFxuICAgICAqIHRyaWdnZXJzIHdyYW5nbGluZyBhbmQgcmUtcmVuZGVyaW5nXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGEgZGF0YSBvYmplY3RcbiAgICAgKiBAcmV0dXJuIHsqfSAtLS1cbiAgICAgKi9cbiAgICB1cGRhdGUoZGF0YTogRGF0YUludGVyZmFjZSkge1xuICAgICAgICB0aGlzLl9kYXRhID0gZGF0YTtcbiAgICAgICAgaWYgKHRoaXMuX3Zpc2liaWxpdHkuaGlkZGVuKSByZXR1cm47XG4gICAgICAgIHRoaXMucmVuZGVyRGF0YSA9IHRoaXMuX3dyYW5nbGUoZGF0YSk7XG4gICAgICAgIHRoaXMuX3JlbmRlcih0aGlzLnJlbmRlckRhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERhdGEgd3JhbmdsaW5nIG1ldGhvZCAtLSBpbXBsZW1lbnQgaW4gc3ViY2xhc3MuIFJldHVybnMgdGhpcy5yZW5kZXJEYXRhLlxuICAgICAqIFNpbXBsZXN0IGltcGxlbWVudGF0aW9uOiBgcmV0dXJuIGRhdGE7YFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIGRhdGFcbiAgICAgKiBAcmV0dXJucyB7Kn0gLS0gZGF0YSBpbiByZW5kZXIgZm9ybWF0XG4gICAgICogQGFic3RyYWN0XG4gICAgICovXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IF93cmFuZ2xlKGRhdGEpO1xuXG5cbiAgICAvKipcbiAgICAgKiBJcyByZXNwb25zaWJsZSBmb3IgbWFwcGluZyBkYXRhIHRvIERPTSBlbGVtZW50c1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSByZW5kZXJEYXRhIHByZS1wcm9jZXNzZWQgKHdyYW5nbGVkKSBkYXRhXG4gICAgICogQGFic3RyYWN0XG4gICAgICogQHJldHVybnMgeyp9IC0tLVxuICAgICAqL1xuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBfcmVuZGVyKHJlbmRlckRhdGEpOiB2b2lkO1xuXG5cbiAgICAvLyBVUERBVEUgT1BUSU9OUyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIGluc3RhbmNlIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBvbmx5IHRoZSBvcHRpb25zIHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWRcbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IHJlUmVuZGVyIGlmIG9wdGlvbiBjaGFuZ2UgcmVxdWlyZXMgYSByZS1yZW5kZXJpbmcgKGRlZmF1bHQ6ZmFsc2UpXG4gICAgICogQHJldHVybnMgeyp9IC0tLVxuICAgICAqL1xuICAgIHVwZGF0ZU9wdGlvbnMoe29wdGlvbnMsIHJlUmVuZGVyID0gZmFsc2V9KSB7XG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2goayA9PiB0aGlzLm9wdGlvbnNba10gPSBvcHRpb25zW2tdKTtcbiAgICAgICAgaWYgKHJlUmVuZGVyKSB0aGlzLl9yZW5kZXIodGhpcy5yZW5kZXJEYXRhKTtcbiAgICB9XG5cblxuICAgIC8vID09PSBDT05WRU5JRU5DRSA9PT09XG4gICAgcmVkcmF3KCl7XG4gICAgICAgIHRoaXMuX3JlbmRlcih0aGlzLnJlbmRlckRhdGEpO1xuICAgIH1cblxuICAgIHNldEhpZGVFbGVtZW50KGhFOiBEM1NlbCkge1xuICAgICAgICB0aGlzLl92aXNpYmlsaXR5LmhpZGVFbGVtZW50ID0gaEU7XG4gICAgfVxuXG4gICAgaGlkZVZpZXcoKSB7XG4gICAgICAgIGlmICghdGhpcy5fdmlzaWJpbGl0eS5oaWRkZW4pIHtcbiAgICAgICAgICAgIGNvbnN0IGhFID0gdGhpcy5fdmlzaWJpbGl0eS5oaWRlRWxlbWVudCB8fCB0aGlzLnBhcmVudDtcbiAgICAgICAgICAgIGhFLnRyYW5zaXRpb24oKS5zdHlsZXMoe1xuICAgICAgICAgICAgICAgICdvcGFjaXR5JzogMCxcbiAgICAgICAgICAgICAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZSdcbiAgICAgICAgICAgIH0pLnN0eWxlKCdkaXNwbGF5JywgJ25vbmUnKTtcbiAgICAgICAgICAgIHRoaXMuX3Zpc2liaWxpdHkuaGlkZGVuID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVuaGlkZVZpZXcoKSB7XG4gICAgICAgIGlmICh0aGlzLl92aXNpYmlsaXR5LmhpZGRlbikge1xuICAgICAgICAgICAgY29uc3QgaEUgPSB0aGlzLl92aXNpYmlsaXR5LmhpZGVFbGVtZW50IHx8IHRoaXMucGFyZW50O1xuICAgICAgICAgICAgaEUudHJhbnNpdGlvbigpLnN0eWxlcyh7XG4gICAgICAgICAgICAgICAgJ29wYWNpdHknOiAxLFxuICAgICAgICAgICAgICAgICdwb2ludGVyLWV2ZW50cyc6IG51bGwsXG4gICAgICAgICAgICAgICAgJ2Rpc3BsYXknOiBudWxsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3Zpc2liaWxpdHkuaGlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAvLyB0aGlzLnVwZGF0ZSh0aGlzLmRhdGEpO1xuXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmJhc2UucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuYmFzZS5odG1sKCcnKTtcbiAgICB9XG5cbn0iLCJpbXBvcnQgKiBhcyBkMyBmcm9tICdkMyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gXCJsb2Rhc2hcIlxuaW1wb3J0ICogYXMgUiBmcm9tICdyYW1kYSdcbmltcG9ydCAqIGFzIHRwIGZyb20gJy4uL2V0Yy90eXBlcyc7XG5pbXBvcnQgKiBhcyByc3AgZnJvbSAnLi4vYXBpL3Jlc3BvbnNlcyc7XG5pbXBvcnQgJy4uL2V0Yy94ZDMnXG5pbXBvcnQgeyBBUEkgfSBmcm9tICcuLi9hcGkvbWFpbkFwaSdcbmltcG9ydCB7IFVJQ29uZmlnIH0gZnJvbSAnLi4vdWlDb25maWcnXG5pbXBvcnQgeyBUZXh0VG9rZW5zLCBMZWZ0VGV4dFRva2VuLCBSaWdodFRleHRUb2tlbiB9IGZyb20gJy4vVGV4dFRva2VuJ1xuaW1wb3J0IHsgQXR0ZW50aW9uSGVhZEJveCwgZ2V0QXR0ZW50aW9uSW5mbyB9IGZyb20gJy4vQXR0ZW50aW9uSGVhZEJveCdcbmltcG9ydCB7IEF0dGVudGlvbkdyYXBoIH0gZnJvbSAnLi9BdHRlbnRpb25Db25uZWN0b3InXG5pbXBvcnQgeyBDb3JwdXNJbnNwZWN0b3IgfSBmcm9tICcuL0NvcnB1c0luc3BlY3RvcidcbmltcG9ydCB7IFRva2VuV3JhcHBlciwgc2lkZVRvTGV0dGVyIH0gZnJvbSAnLi4vZGF0YS9Ub2tlbldyYXBwZXInXG5pbXBvcnQgeyBBdHRlbnRpb25XcmFwcGVyLCBtYWtlRnJvbU1ldGFSZXNwb25zZSB9IGZyb20gJy4uL2RhdGEvQXR0ZW50aW9uQ2Fwc3VsZSdcbmltcG9ydCB7IFNpbXBsZUV2ZW50SGFuZGxlciB9IGZyb20gJy4uL2V0Yy9TaW1wbGVFdmVudEhhbmRsZXInXG5pbXBvcnQgeyBDb3JwdXNNYXRNYW5hZ2VyIH0gZnJvbSAnLi4vdmlzL0NvcnB1c01hdE1hbmFnZXInXG5pbXBvcnQgeyBDb3JwdXNIaXN0b2dyYW0gfSBmcm9tICcuLi92aXMvQ29ycHVzSGlzdG9ncmFtJ1xuaW1wb3J0IHsgRmFpc3NTZWFyY2hSZXN1bHRXcmFwcGVyIH0gZnJvbSAnLi4vZGF0YS9GYWlzc1NlYXJjaFdyYXBwZXInXG5pbXBvcnQgeyBEM1NlbCwgU2VsIH0gZnJvbSAnLi4vZXRjL1V0aWwnO1xuaW1wb3J0IHsgZnJvbSwgZnJvbUV2ZW50LCBpbnRlcnZhbCB9IGZyb20gJ3J4anMnXG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnXG5pbXBvcnQgeyBCYXNlVHlwZSB9IGZyb20gXCJkM1wiO1xuaW1wb3J0IHsgU2ltcGxlTWV0YSB9IGZyb20gXCIuLi9ldGMvdHlwZXNcIjtcbmltcG9ydCBDaGFuZ2VFdmVudCA9IEpRdWVyeS5DaGFuZ2VFdmVudDtcblxuXG5mdW5jdGlvbiBpc051bGxUb2tlbih0b2s6IHRwLlRva2VuRXZlbnQpIHtcbiAgICBjb25zdCBpc1NvbWVOdWxsID0geCA9PiB7XG4gICAgICAgIHJldHVybiAoeCA9PSBudWxsKSB8fCAoeCA9PSBcIm51bGxcIilcbiAgICB9XG4gICAgY29uc3QgdG9rSXNOdWxsID0gdG9rID09IG51bGw7XG4gICAgY29uc3QgdG9rSGFzTnVsbCA9IGlzU29tZU51bGwodG9rLnNpZGUpIHx8IGlzU29tZU51bGwodG9rLmluZClcbiAgICByZXR1cm4gdG9rSXNOdWxsIHx8IHRva0hhc051bGxcbn1cblxuZnVuY3Rpb24gc2hvd0J5U2lkZShlOiB0cC5Ub2tlbkV2ZW50KSB7XG4gICAgLy8gQ2hlY2sgaWYgc2F2ZWQgdG9rZW4gaW4gdWlDb25mIGlzIG51bGxcbiAgICBpZiAoIWlzTnVsbFRva2VuKGUpKSB7XG4gICAgICAgIGNvbnN0IGNsYXNzU2VsZWN0b3IgPSBlLnNpZGUgPT0gXCJsZWZ0XCIgPyBcInNyYy1pZHhcIiA6IFwidGFyZ2V0LWlkeFwiO1xuXG4gICAgICAgIFNlbC5zZXRIaWRkZW4oXCIuYXRuLWN1cnZlXCIpXG4gICAgICAgIFNlbC5zZXRWaXNpYmxlKGAuYXRuLWN1cnZlWyR7Y2xhc3NTZWxlY3Rvcn09JyR7ZS5pbmR9J11gKVxuICAgIH1cbn1cblxuZnVuY3Rpb24gY2hvb3NlU2hvd0J5U2lkZShzYXZlZEV2ZW50OiB0cC5Ub2tlbkV2ZW50LCBuZXdFdmVudDogdHAuVG9rZW5FdmVudCkge1xuICAgIGlmIChpc051bGxUb2tlbihzYXZlZEV2ZW50KSkge1xuICAgICAgICBzaG93QnlTaWRlKG5ld0V2ZW50KVxuICAgIH1cbn1cblxuZnVuY3Rpb24gY2hvb3NlU2hvd0FsbChzYXZlZEV2ZW50OiB0cC5Ub2tlbkV2ZW50KSB7XG4gICAgaWYgKGlzTnVsbFRva2VuKHNhdmVkRXZlbnQpKVxuICAgICAgICBTZWwuc2V0VmlzaWJsZShcIi5hdG4tY3VydmVcIilcbn1cblxuZnVuY3Rpb24gdW5zZWxlY3RIZWFkKGhlYWQ6IG51bWJlcikge1xuICAgIGNvbnN0IGFmZmVjdGVkSGVhZHMgPSBkMy5zZWxlY3RBbGwoYC5hdHQtcmVjdFtoZWFkPScke2hlYWR9J11gKTtcbiAgICBhZmZlY3RlZEhlYWRzLmNsYXNzZWQoXCJ1bnNlbGVjdGVkXCIsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHNlbGVjdEhlYWQoaGVhZDogbnVtYmVyKSB7XG4gICAgY29uc3QgYWZmZWN0ZWRIZWFkcyA9IGQzLnNlbGVjdEFsbChgLmF0dC1yZWN0W2hlYWQ9JyR7aGVhZH0nXWApO1xuICAgIGFmZmVjdGVkSGVhZHMuY2xhc3NlZChcInVuc2VsZWN0ZWRcIiwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHNldFNlbERpc2FibGVkKGF0dHI6IGJvb2xlYW4sIHNlbDogRDNTZWwpIHtcbiAgICBjb25zdCB2YWwgPSBhdHRyID8gdHJ1ZSA6IG51bGxcbiAgICBzZWwuYXR0cignZGlzYWJsZWQnLCB2YWwpXG59XG5cblxuZXhwb3J0IGNsYXNzIE1haW5HcmFwaGljIHtcbiAgICBhcGk6IEFQSVxuICAgIHVpQ29uZjogVUlDb25maWdcbiAgICBhdHRDYXBzdWxlOiBBdHRlbnRpb25XcmFwcGVyXG4gICAgdG9rQ2Fwc3VsZTogVG9rZW5XcmFwcGVyXG4gICAgc2VsczogYW55ICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29udGFpbnMgaW5pdGlhbCBkMyBzZWxlY3Rpb25zIG9mIG9iamVjdHNcbiAgICB2aXpzOiBhbnkgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDb250YWlucyB2aXMgY29tcG9uZW50cyB3cmFwcGVkIGFyb3VuZCBwYXJlbnQgc2VsXG4gICAgZXZlbnRIYW5kbGVyOiBTaW1wbGVFdmVudEhhbmRsZXIgICAgLy8gT3JjaGVzdHJhdGVzIGV2ZW50cyByYWlzZWQgZnJvbSBjb21wb25lbnRzXG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5hcGkgPSBuZXcgQVBJKClcbiAgICAgICAgdGhpcy51aUNvbmYgPSBuZXcgVUlDb25maWcoKVxuICAgICAgICB0aGlzLnNrZWxldG9uSW5pdCgpXG4gICAgICAgIHRoaXMubWFpbkluaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbnMgdGhhdCBjYW4gYmUgY2FsbGVkIHdpdGhvdXQgYW55IGluZm9ybWF0aW9uIG9mIGEgcmVzcG9uc2UuXG4gICAgICogXG4gICAgICogVGhpcyBzaG91bGQgYmUgY2FsbGVkIG9uY2UgYW5kIG9ubHkgb25jZVxuICAgICAqL1xuICAgIHNrZWxldG9uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5zZWxzID0ge1xuICAgICAgICAgICAgYm9keTogZDMuc2VsZWN0KCdib2R5JyksXG4gICAgICAgICAgICBhdG5Db250YWluZXI6IGQzLnNlbGVjdCgnI2F0bi1jb250YWluZXInKSxcbiAgICAgICAgICAgIGF0bkRpc3BsYXk6IGQzLnNlbGVjdChcIiNhdG4tZGlzcGxheVwiKSxcbiAgICAgICAgICAgIG1vZGVsU2VsZWN0b3I6IGQzLnNlbGVjdChcIiNtb2RlbC1vcHRpb24tc2VsZWN0b3JcIiksXG4gICAgICAgICAgICBjb3JwdXNTZWxlY3RvcjogZDMuc2VsZWN0KFwiI2NvcnB1cy1zZWxlY3RcIiksXG4gICAgICAgICAgICBhdG5IZWFkczoge1xuICAgICAgICAgICAgICAgIGxlZnQ6IGQzLnNlbGVjdChcIiNsZWZ0LWF0dC1oZWFkc1wiKSxcbiAgICAgICAgICAgICAgICByaWdodDogZDMuc2VsZWN0KFwiI3JpZ2h0LWF0dC1oZWFkc1wiKSxcbiAgICAgICAgICAgICAgICBoZWFkSW5mbzogZDMuc2VsZWN0KFwiI2hlYWQtaW5mby1ib3hcIilcbiAgICAgICAgICAgICAgICAgICAgLmNsYXNzZWQoJ21hdC1ob3Zlci1kaXNwbGF5JywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgLmNsYXNzZWQoJ3RleHQtY2VudGVyJywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgLnN0eWxlKCd3aWR0aCcsIFN0cmluZyg3MCkgKyAncHgnKVxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoJ2hlaWdodCcsIFN0cmluZygzMCkgKyAncHgnKVxuICAgICAgICAgICAgICAgICAgICAuc3R5bGUoJ3Zpc2liaWxsaXR5JywgJ2hpZGRlbicpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZm9ybToge1xuICAgICAgICAgICAgICAgIHNlbnRlbmNlQTogZDMuc2VsZWN0KFwiI2Zvcm0tc2VudGVuY2UtYVwiKSxcbiAgICAgICAgICAgICAgICBidXR0b246IGQzLnNlbGVjdChcIiN1cGRhdGUtc2VudGVuY2VcIiksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdG9rZW5zOiB7XG4gICAgICAgICAgICAgICAgbGVmdDogZDMuc2VsZWN0KFwiI2xlZnQtdG9rZW5zXCIpLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiBkMy5zZWxlY3QoXCIjcmlnaHQtdG9rZW5zXCIpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNsc1RvZ2dsZTogZDMuc2VsZWN0KFwiI2Nscy10b2dnbGVcIikuc2VsZWN0KFwiLnN3aXRjaFwiKSxcbiAgICAgICAgICAgIGxheWVyQ2hlY2tib3hlczogZDMuc2VsZWN0KFwiI2xheWVyLXNlbGVjdFwiKSxcbiAgICAgICAgICAgIGhlYWRDaGVja2JveGVzOiBkMy5zZWxlY3QoXCIjaGVhZC1zZWxlY3RcIiksXG4gICAgICAgICAgICBjb250ZXh0UXVlcnk6IGQzLnNlbGVjdChcIiNzZWFyY2gtY29udGV4dHNcIiksXG4gICAgICAgICAgICBlbWJlZGRpbmdRdWVyeTogZDMuc2VsZWN0KFwiI3NlYXJjaC1lbWJlZGRpbmdzXCIpLFxuICAgICAgICAgICAgc2VsZWN0ZWRIZWFkczogZDMuc2VsZWN0KFwiI3NlbGVjdGVkLWhlYWRzXCIpLFxuICAgICAgICAgICAgaGVhZFNlbGVjdEFsbDogZDMuc2VsZWN0KFwiI3NlbGVjdC1hbGwtaGVhZHNcIiksXG4gICAgICAgICAgICBoZWFkU2VsZWN0Tm9uZTogZDMuc2VsZWN0KFwiI3NlbGVjdC1uby1oZWFkc1wiKSxcbiAgICAgICAgICAgIHRlc3RDaGVja2JveDogZDMuc2VsZWN0KFwiI3NpbXBsZS1lbWJlZC1xdWVyeVwiKSxcbiAgICAgICAgICAgIHRocmVzaFNsaWRlcjogZDMuc2VsZWN0KFwiI215LXJhbmdlXCIpLFxuICAgICAgICAgICAgY29ycHVzSW5zcGVjdG9yOiBkMy5zZWxlY3QoXCIjY29ycHVzLXNpbWlsYXItc2VudGVuY2VzLWRpdlwiKSxcbiAgICAgICAgICAgIGNvcnB1c01hdE1hbmFnZXI6IGQzLnNlbGVjdChcIiNjb3JwdXMtbWF0LWNvbnRhaW5lclwiKSxcbiAgICAgICAgICAgIGNvcnB1c01zZ0JveDogZDMuc2VsZWN0KFwiI2NvcnB1cy1tc2ctYm94XCIpLFxuICAgICAgICAgICAgaGlzdG9ncmFtczoge1xuICAgICAgICAgICAgICAgIG1hdGNoZWRXb3JkRGVzY3JpcHRpb246IGQzLnNlbGVjdChcIiNtYXRjaC1raW5kXCIpLFxuICAgICAgICAgICAgICAgIG1hdGNoZWRXb3JkOiBkMy5zZWxlY3QoXCIjbWF0Y2hlZC1oaXN0b2dyYW0tY29udGFpbmVyXCIpLFxuICAgICAgICAgICAgICAgIG1heEF0dDogZDMuc2VsZWN0KFwiI21heC1hdHQtaGlzdG9ncmFtLWNvbnRhaW5lclwiKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBidXR0b25zOiB7XG4gICAgICAgICAgICAgICAga2lsbExlZnQ6IGQzLnNlbGVjdChcIiNraWxsLWxlZnRcIiksXG4gICAgICAgICAgICAgICAgYWRkTGVmdDogZDMuc2VsZWN0KFwiI21pbnVzLWxlZnRcIiksXG4gICAgICAgICAgICAgICAgYWRkUmlnaHQ6IGQzLnNlbGVjdChcIiNwbHVzLXJpZ2h0XCIpLFxuICAgICAgICAgICAgICAgIGtpbGxSaWdodDogZDMuc2VsZWN0KFwiI2tpbGwtcmlnaHRcIiksXG4gICAgICAgICAgICAgICAgcmVmcmVzaDogZDMuc2VsZWN0KFwiI21hdC1yZWZyZXNoXCIpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWV0YVNlbGVjdG9yOiB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlZFdvcmQ6IGQzLnNlbGVjdChcIiNtYXRjaGVkLW1ldGEtc2VsZWN0XCIpLFxuICAgICAgICAgICAgICAgIG1heEF0dDogZDMuc2VsZWN0KFwiI21heC1hdHQtbWV0YS1zZWxlY3RcIilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZXZlbnRIYW5kbGVyID0gbmV3IFNpbXBsZUV2ZW50SGFuZGxlcig8RWxlbWVudD50aGlzLnNlbHMuYm9keS5ub2RlKCkpO1xuXG4gICAgICAgIHRoaXMudml6cyA9IHtcbiAgICAgICAgICAgIGxlZnRIZWFkczogbmV3IEF0dGVudGlvbkhlYWRCb3godGhpcy5zZWxzLmF0bkhlYWRzLmxlZnQsIHRoaXMuZXZlbnRIYW5kbGVyLCB7IHNpZGU6IFwibGVmdFwiLCB9KSxcbiAgICAgICAgICAgIHJpZ2h0SGVhZHM6IG5ldyBBdHRlbnRpb25IZWFkQm94KHRoaXMuc2Vscy5hdG5IZWFkcy5yaWdodCwgdGhpcy5ldmVudEhhbmRsZXIsIHsgc2lkZTogXCJyaWdodFwiIH0pLFxuICAgICAgICAgICAgdG9rZW5zOiB7XG4gICAgICAgICAgICAgICAgbGVmdDogbmV3IExlZnRUZXh0VG9rZW4odGhpcy5zZWxzLnRva2Vucy5sZWZ0LCB0aGlzLmV2ZW50SGFuZGxlciksXG4gICAgICAgICAgICAgICAgcmlnaHQ6IG5ldyBSaWdodFRleHRUb2tlbih0aGlzLnNlbHMudG9rZW5zLnJpZ2h0LCB0aGlzLmV2ZW50SGFuZGxlciksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXR0ZW50aW9uU3ZnOiBuZXcgQXR0ZW50aW9uR3JhcGgodGhpcy5zZWxzLmF0bkRpc3BsYXksIHRoaXMuZXZlbnRIYW5kbGVyKSxcbiAgICAgICAgICAgIGNvcnB1c0luc3BlY3RvcjogbmV3IENvcnB1c0luc3BlY3Rvcih0aGlzLnNlbHMuY29ycHVzSW5zcGVjdG9yLCB0aGlzLmV2ZW50SGFuZGxlciksXG4gICAgICAgICAgICBjb3JwdXNNYXRNYW5hZ2VyOiBuZXcgQ29ycHVzTWF0TWFuYWdlcih0aGlzLnNlbHMuY29ycHVzTWF0TWFuYWdlciwgdGhpcy5ldmVudEhhbmRsZXIsIHsgaWR4czogdGhpcy51aUNvbmYub2Zmc2V0SWR4cygpIH0pLFxuICAgICAgICAgICAgaGlzdG9ncmFtczoge1xuICAgICAgICAgICAgICAgIG1hdGNoZWRXb3JkOiBuZXcgQ29ycHVzSGlzdG9ncmFtKHRoaXMuc2Vscy5oaXN0b2dyYW1zLm1hdGNoZWRXb3JkLCB0aGlzLmV2ZW50SGFuZGxlciksXG4gICAgICAgICAgICAgICAgbWF4QXR0OiBuZXcgQ29ycHVzSGlzdG9ncmFtKHRoaXMuc2Vscy5oaXN0b2dyYW1zLm1heEF0dCwgdGhpcy5ldmVudEhhbmRsZXIpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2JpbmRFdmVudEhhbmRsZXIoKVxuICAgIH1cblxuICAgIHByaXZhdGUgbWFpbkluaXQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgICB0aGlzLnNlbHMuYm9keS5zdHlsZShcImN1cnNvclwiLCBcInByb2dyZXNzXCIpXG4gICAgICAgIHRoaXMuYXBpLmdldE1vZGVsRGV0YWlscyh0aGlzLnVpQ29uZi5tb2RlbCgpKS50aGVuKG1kID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbCA9IG1kLnBheWxvYWRcbiAgICAgICAgICAgIHRoaXMudWlDb25mLm5MYXllcnModmFsLm5sYXllcnMpLm5IZWFkcyh2YWwubmhlYWRzKVxuICAgICAgICAgICAgdGhpcy5pbml0TGF5ZXJzKHRoaXMudWlDb25mLm5MYXllcnMoKSlcblxuICAgICAgICAgICAgdGhpcy5hcGkuZ2V0TWV0YUF0dGVudGlvbnModGhpcy51aUNvbmYubW9kZWwoKSwgdGhpcy51aUNvbmYuc2VudGVuY2UoKSwgdGhpcy51aUNvbmYubGF5ZXIoKSkudGhlbihhdHRlbnRpb24gPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF0dCA9IGF0dGVudGlvbi5wYXlsb2FkO1xuICAgICAgICAgICAgICAgIHRoaXMuaW5pdEZyb21SZXNwb25zZShhdHQpXG5cbiAgICAgICAgICAgICAgICAvLyBXcmFwIHBvc3RJbml0IGludG8gZnVuY3Rpb24gc28gYXN5bmNocm9ub3VzIGNhbGwgZG9lcyBub3QgbWVzcyB3aXRoIG5lY2Vzc2FyeSBpbml0c1xuICAgICAgICAgICAgICAgIGNvbnN0IHBvc3RSZXNwb25zZURpc3BsYXlDbGVhbnVwID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90b2dnbGVUb2tlblNlbCgpXG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdG9EaXNwbGF5ID0gdGhpcy51aUNvbmYuZGlzcGxheUluc3BlY3RvcigpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NlYXJjaERpc2FibGVyKClcblxuICAgICAgICAgICAgICAgICAgICBpZiAodG9EaXNwbGF5ID09ICdjb250ZXh0Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fcXVlcnlDb250ZXh0KClcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0b0Rpc3BsYXkgPT0gJ2VtYmVkZGluZ3MnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9xdWVyeUVtYmVkZGluZ3MoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IG5vcm1CeVxuICAgICAgICAgICAgICAgIGlmICgodGhpcy51aUNvbmYubW9kZWxLaW5kKCkgPT0gdHAuTW9kZWxLaW5kLkF1dG9yZWdyZXNzaXZlKSAmJiAoIXRoaXMudWlDb25mLmhpZGVDbHNTZXAoKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9ybUJ5ID0gdHAuTm9ybUJ5LkNvbFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbm9ybUJ5ID0gdHAuTm9ybUJ5LkFsbFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnZpenMuYXR0ZW50aW9uU3ZnLm5vcm1CeSA9IG5vcm1CeVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudWlDb25mLm1hc2tJbmRzKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRva0NhcHN1bGUuYS5tYXNrSW5kcyA9IHRoaXMudWlDb25mLm1hc2tJbmRzKClcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFwaS51cGRhdGVNYXNrZWRBdHRlbnRpb25zKHRoaXMudWlDb25mLm1vZGVsKCksIHRoaXMudG9rQ2Fwc3VsZS5hLCB0aGlzLnVpQ29uZi5zZW50ZW5jZSgpLCB0aGlzLnVpQ29uZi5sYXllcigpKS50aGVuKHJlc3AgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgciA9IHJlc3AucGF5bG9hZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXR0Q2Fwc3VsZS51cGRhdGVGcm9tTm9ybWFsKHIsIHRoaXMudWlDb25mLmhpZGVDbHNTZXAoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRva0NhcHN1bGUudXBkYXRlVG9rZW5zKHIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZSgpXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3N0UmVzcG9uc2VEaXNwbGF5Q2xlYW51cCgpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGUoKVxuICAgICAgICAgICAgICAgICAgICBwb3N0UmVzcG9uc2VEaXNwbGF5Q2xlYW51cCgpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudWlDb25mLm1vZGVsS2luZCgpID09IHRwLk1vZGVsS2luZC5BdXRvcmVncmVzc2l2ZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBFbnN1cmUgb25seSAxIG1hc2sgaW5kIGlzIHByZXNlbnQgZm9yIGF1dG9yZWdyZXNzaXZlIG1vZGVsc1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy51aUNvbmYuaGFzVG9rZW4oKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ncmF5VG9nZ2xlKDxudW1iZXI+dGhpcy51aUNvbmYudG9rZW4oKS5pbmQpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLnRva2Vucy5sZWZ0Lm9wdGlvbnMuZGl2SG92ZXIudGV4dEluZm8gPSBcIldvdWxkIHByZWRpY3QgbmV4dC4uLlwiXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudml6cy50b2tlbnMucmlnaHQub3B0aW9ucy5kaXZIb3Zlci50ZXh0SW5mbyA9IFwiV291bGQgcHJlZGljdCBuZXh0Li4uXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYudml6cy50b2tlbnMubGVmdC5vcHRpb25zLmRpdkhvdmVyLnRleHRJbmZvID0gXCJXb3VsZCBwcmVkaWN0IGhlcmUuLi5cIlxuICAgICAgICAgICAgICAgICAgICBzZWxmLnZpenMudG9rZW5zLnJpZ2h0Lm9wdGlvbnMuZGl2SG92ZXIudGV4dEluZm8gPSBcIldvdWxkIHByZWRpY3QgaGVyZS4uLlwiXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxzLmJvZHkuc3R5bGUoXCJjdXJzb3JcIiwgXCJkZWZhdWx0XCIpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcblxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEZyb21SZXNwb25zZShhdHRlbnRpb246IHRwLkF0dGVudGlvblJlc3BvbnNlKSB7XG4gICAgICAgIHRoaXMuYXR0Q2Fwc3VsZSA9IG1ha2VGcm9tTWV0YVJlc3BvbnNlKGF0dGVudGlvbiwgdGhpcy51aUNvbmYuaGlkZUNsc1NlcCgpKVxuICAgICAgICB0aGlzLnRva0NhcHN1bGUgPSBuZXcgVG9rZW5XcmFwcGVyKGF0dGVudGlvbik7XG4gICAgICAgIHRoaXMuX3N0YXRpY0luaXRzKClcbiAgICB9XG5cbiAgICBwcml2YXRlIGxlYXZlQ29ycHVzTXNnKG1zZzogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudml6cy5jb3JwdXNJbnNwZWN0b3IuaGlkZVZpZXcoKVxuICAgICAgICB0aGlzLnZpenMuY29ycHVzTWF0TWFuYWdlci5oaWRlVmlldygpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiUnVubmluZyBsZWF2ZSBtc2dcIik7XG4gICAgICAgIFNlbC51bmhpZGVFbGVtZW50KHRoaXMuc2Vscy5jb3JwdXNNc2dCb3gpXG4gICAgICAgIHRoaXMuc2Vscy5jb3JwdXNNc2dCb3gudGV4dChtc2cpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfYmluZEV2ZW50SGFuZGxlcigpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIHRoaXMuZXZlbnRIYW5kbGVyLmJpbmQoVGV4dFRva2Vucy5ldmVudHMudG9rZW5EYmxDbGljaywgKGUpID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAoc2VsZi51aUNvbmYubW9kZWxLaW5kKCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIHRwLk1vZGVsS2luZC5CaWRpcmVjdGlvbmFsOiB7XG4gICAgICAgICAgICAgICAgICAgIGUuc2VsLmNsYXNzZWQoXCJtYXNrZWQtdG9rZW5cIiwgIWUuc2VsLmNsYXNzZWQoXCJtYXNrZWQtdG9rZW5cIikpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZXR0ZXIgPSBzaWRlVG9MZXR0ZXIoZS5zaWRlLCB0aGlzLnVpQ29uZi5hdHRUeXBlKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnRva0NhcHN1bGVbbGV0dGVyXS50b2dnbGUoZS5pbmQpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2Vscy5ib2R5LnN0eWxlKFwiY3Vyc29yXCIsIFwicHJvZ3Jlc3NcIilcblxuICAgICAgICAgICAgICAgICAgICBzZWxmLmFwaS51cGRhdGVNYXNrZWRBdHRlbnRpb25zKHRoaXMudWlDb25mLm1vZGVsKCksIHRoaXMudG9rQ2Fwc3VsZS5hLCB0aGlzLnVpQ29uZi5zZW50ZW5jZSgpLCB0aGlzLnVpQ29uZi5sYXllcigpKS50aGVuKChyZXNwOiByc3AuQXR0ZW50aW9uRGV0YWlsc1Jlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByID0gcmVzcC5wYXlsb2FkO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hdHRDYXBzdWxlLnVwZGF0ZUZyb21Ob3JtYWwociwgdGhpcy51aUNvbmYuaGlkZUNsc1NlcCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYudG9rQ2Fwc3VsZS51cGRhdGVUb2tlbnMocik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYudWlDb25mLm1hc2tJbmRzKHRoaXMudG9rQ2Fwc3VsZS5hLm1hc2tJbmRzKVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zZWxzLmJvZHkuc3R5bGUoXCJjdXJzb3JcIiwgXCJkZWZhdWx0XCIpXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIHRwLk1vZGVsS2luZC5BdXRvcmVncmVzc2l2ZToge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkF1dG9yZWdyZXNzaXZlIG1vZGVsIGRvZXNuJ3QgZG8gbWFza2luZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJXaGF0IGtpbmQgb2YgbW9kZWwgaXMgdGhpcz9cIik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5iaW5kKFRleHRUb2tlbnMuZXZlbnRzLnRva2VuTW91c2VPdmVyLCAoZTogdHAuVG9rZW5FdmVudCkgPT4ge1xuICAgICAgICAgICAgY2hvb3NlU2hvd0J5U2lkZSh0aGlzLnVpQ29uZi50b2tlbigpLCBlKVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuZXZlbnRIYW5kbGVyLmJpbmQoVGV4dFRva2Vucy5ldmVudHMudG9rZW5Nb3VzZU91dCwgKGUpID0+IHtcbiAgICAgICAgICAgIGNob29zZVNob3dBbGwodGhpcy51aUNvbmYudG9rZW4oKSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5iaW5kKFRleHRUb2tlbnMuZXZlbnRzLnRva2VuQ2xpY2ssIChlOiB0cC5Ub2tlbkV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b2tUb2dnbGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51aUNvbmYudG9nZ2xlVG9rZW4oZSlcbiAgICAgICAgICAgICAgICB0aGlzLl90b2dnbGVUb2tlblNlbCgpXG4gICAgICAgICAgICAgICAgc2hvd0J5U2lkZShlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdG9rVG9nZ2xlKClcbiAgICAgICAgICAgIHRoaXMucmVuZGVyQXR0SGVhZCgpXG4gICAgICAgIH0pXG5cblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5iaW5kKEF0dGVudGlvbkhlYWRCb3guZXZlbnRzLnJvd01vdXNlT3ZlciwgKGU6IHRwLkhlYWRCb3hFdmVudCkgPT4ge1xuICAgICAgICAgICAgc2VsZi5zZWxzLmF0bkhlYWRzLmhlYWRJbmZvLnN0eWxlKCd2aXNpYmlsaXR5JywgJ3Zpc2libGUnKVxuICAgICAgICB9KVxuXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5yb3dNb3VzZU91dCwgKCkgPT4ge1xuICAgICAgICAgICAgc2VsZi5zZWxzLmF0bkhlYWRzLmhlYWRJbmZvLnN0eWxlKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpXG4gICAgICAgICAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBzcGVjaWFsIG9uIHJvdyBtb3VzZSBvdXRcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5iaW5kKEF0dGVudGlvbkhlYWRCb3guZXZlbnRzLmJveE1vdXNlT3ZlciwgKGU6IHRwLkhlYWRCb3hFdmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlTWF0ID0gdGhpcy5hdHRDYXBzdWxlLmJ5SGVhZChlLmhlYWQpXG4gICAgICAgICAgICB0aGlzLnZpenMuYXR0ZW50aW9uU3ZnLmRhdGEodXBkYXRlTWF0KVxuICAgICAgICAgICAgdGhpcy52aXpzLmF0dGVudGlvblN2Zy51cGRhdGUodXBkYXRlTWF0KVxuXG4gICAgICAgICAgICBzaG93QnlTaWRlKHRoaXMudWlDb25mLnRva2VuKCkpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hNb3VzZU91dCwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXR0ID0gdGhpcy5hdHRDYXBzdWxlLmJ5SGVhZHModGhpcy51aUNvbmYuaGVhZHMoKSlcbiAgICAgICAgICAgIHRoaXMudml6cy5hdHRlbnRpb25TdmcuZGF0YShhdHQpXG4gICAgICAgICAgICB0aGlzLnZpenMuYXR0ZW50aW9uU3ZnLnVwZGF0ZShhdHQpXG4gICAgICAgICAgICBzaG93QnlTaWRlKHRoaXMudWlDb25mLnRva2VuKCkpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hNb3VzZU1vdmUsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBoZWFkSW5mbyA9IHNlbGYuc2Vscy5hdG5IZWFkcy5oZWFkSW5mb1xuICAgICAgICAgICAgbGV0IGxlZnQsIHRvcCwgYm9yZGVyUmFkaXVzXG5cbiAgICAgICAgICAgIGlmIChlLnNpZGUgPT0gXCJsZWZ0XCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXZPZmZzZXQgPSBbMTIsIDNdXG4gICAgICAgICAgICAgICAgbGVmdCA9IGUubW91c2VbMF0gKyBlLmJhc2VYIC0gKCtoZWFkSW5mby5zdHlsZSgnd2lkdGgnKS5yZXBsYWNlKCdweCcsICcnKSArIGRpdk9mZnNldFswXSlcbiAgICAgICAgICAgICAgICB0b3AgPSBlLm1vdXNlWzFdICsgZS5iYXNlWSAtICgraGVhZEluZm8uc3R5bGUoJ2hlaWdodCcpLnJlcGxhY2UoJ3B4JywgJycpICsgZGl2T2Zmc2V0WzFdKVxuICAgICAgICAgICAgICAgIGJvcmRlclJhZGl1cyA9IFwiOHB4IDhweCAxcHggOHB4XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpdk9mZnNldCA9IFstMTMsIDNdXG4gICAgICAgICAgICAgICAgbGVmdCA9IGUubW91c2VbMF0gKyBlLmJhc2VYICsgZGl2T2Zmc2V0WzBdXG4gICAgICAgICAgICAgICAgdG9wID0gZS5tb3VzZVsxXSArIGUuYmFzZVkgLSAoK2hlYWRJbmZvLnN0eWxlKCdoZWlnaHQnKS5yZXBsYWNlKCdweCcsICcnKSArIGRpdk9mZnNldFsxXSlcbiAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXMgPSBcIjhweCA4cHggOHB4IDFweFwiXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGhlYWRJbmZvXG4gICAgICAgICAgICAgICAgLnN0eWxlKCd2aXNpYmlsaXR5JywgJ3Zpc2libGUnKVxuICAgICAgICAgICAgICAgIC5zdHlsZSgnbGVmdCcsIFN0cmluZyhsZWZ0KSArICdweCcpXG4gICAgICAgICAgICAgICAgLnN0eWxlKCd0b3AnLCBTdHJpbmcodG9wKSArICdweCcpXG4gICAgICAgICAgICAgICAgLnN0eWxlKCdib3JkZXItcmFkaXVzJywgYm9yZGVyUmFkaXVzKVxuICAgICAgICAgICAgICAgIC50ZXh0KGBIZWFkOiAke2UuaW5kICsgMX1gKVxuXG4gICAgICAgICAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBzcGVjaWFsIG9uIHJvdyBtb3VzZSBvdmVyXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChBdHRlbnRpb25IZWFkQm94LmV2ZW50cy5ib3hDbGljaywgKGU6IHsgaGVhZCB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnVpQ29uZi50b2dnbGVIZWFkKGUuaGVhZClcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gdHAuVG9nZ2xlZC5BRERFRCkge1xuICAgICAgICAgICAgICAgIHNlbGVjdEhlYWQoZS5oZWFkKVxuICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQgPT0gdHAuVG9nZ2xlZC5SRU1PVkVEKSB7XG4gICAgICAgICAgICAgICAgdW5zZWxlY3RIZWFkKGUuaGVhZClcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fc2VhcmNoRGlzYWJsZXIoKVxuICAgICAgICAgICAgdGhpcy5fcmVuZGVySGVhZFN1bW1hcnkoKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU3ZnKCk7XG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChDb3JwdXNNYXRNYW5hZ2VyLmV2ZW50cy5tb3VzZU92ZXIsIChlOiB7IHZhbDogXCJwb3NcIiB8IFwiZGVwXCIgfCBcImlzX2VudFwiLCBvZmZzZXQ6IG51bWJlciB9KSA9PiB7XG4gICAgICAgICAgICAvLyBVbmNvbW1lbnQgdGhlIGJlbG93IGlmIHlvdSB3YW50IHRvIG1vZGlmeSB0aGUgd2hvbGUgY29sdW1uXG4gICAgICAgICAgICAvLyBjb25zdCBzZWxlY3RvciA9IGAuaW5zcGVjdG9yLWNlbGxbaW5kZXgtb2Zmc2V0PScke2Uub2Zmc2V0fSddYFxuICAgICAgICAgICAgLy8gZDMuc2VsZWN0QWxsKHNlbGVjdG9yKS5jbGFzc2VkKFwiaG92ZXJlZC1jb2xcIiwgdHJ1ZSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlci5iaW5kKENvcnB1c01hdE1hbmFnZXIuZXZlbnRzLm1vdXNlT3V0LCAoZTogeyBvZmZzZXQ6IG51bWJlciwgaWR4OiBudW1iZXIgfSkgPT4ge1xuICAgICAgICAgICAgLy8gVW5jb21tZW50IHRoZSBiZWxvdyBpZiB5b3Ugd2FudCB0byBtb2RpZnkgdGhlIHdob2xlIGNvbHVtblxuICAgICAgICAgICAgLy8gY29uc3Qgc2VsZWN0b3IgPSBgLmluc3BlY3Rvci1jZWxsW2luZGV4LW9mZnNldD0nJHtlLm9mZnNldH0nXWBcbiAgICAgICAgICAgIC8vIGQzLnNlbGVjdEFsbChzZWxlY3RvcikuY2xhc3NlZChcImhvdmVyZWQtY29sXCIsIGZhbHNlKVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuZXZlbnRIYW5kbGVyLmJpbmQoQ29ycHVzTWF0TWFuYWdlci5ldmVudHMucmVjdE1vdXNlT3ZlciwgKGU6IHsgb2Zmc2V0OiBudW1iZXIsIGlkeDogbnVtYmVyIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJvdyA9IGQzLnNlbGVjdChgLmluc3BlY3Rvci1yb3dbcm93bnVtPScke2UuaWR4fSddYClcbiAgICAgICAgICAgIGNvbnN0IHdvcmQgPSByb3cuc2VsZWN0KGAuaW5zcGVjdG9yLWNlbGxbaW5kZXgtb2Zmc2V0PScke2Uub2Zmc2V0fSddYClcbiAgICAgICAgICAgIHdvcmQuY2xhc3NlZChcImhvdmVyZWQtY29sXCIsIHRydWUpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5ldmVudEhhbmRsZXIuYmluZChDb3JwdXNNYXRNYW5hZ2VyLmV2ZW50cy5yZWN0TW91c2VPdXQsIChlOiB7IG9mZnNldDogbnVtYmVyLCBpZHg6IG51bWJlciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCByb3cgPSBkMy5zZWxlY3QoYC5pbnNwZWN0b3Itcm93W3Jvd251bT0nJHtlLmlkeH0nXWApXG4gICAgICAgICAgICBjb25zdCB3b3JkID0gcm93LnNlbGVjdChgLmluc3BlY3Rvci1jZWxsW2luZGV4LW9mZnNldD0nJHtlLm9mZnNldH0nXWApXG4gICAgICAgICAgICB3b3JkLmNsYXNzZWQoXCJob3ZlcmVkLWNvbFwiLCBmYWxzZSlcbiAgICAgICAgfSlcblxuICAgIH1cblxuICAgIHByaXZhdGUgX3RvZ2dsZVRva2VuU2VsKCkge1xuICAgICAgICBjb25zdCBlID0gdGhpcy51aUNvbmYudG9rZW4oKVxuICAgICAgICBjb25zdCBhbHJlYWR5U2VsZWN0ZWQgPSBkMy5zZWxlY3QoJy5zZWxlY3RlZC10b2tlbicpXG5cbiAgICAgICAgLy8gSWYgbm8gdG9rZW4gc2hvdWxkIGJlIHNlbGVjdGVkLCB1bnNlbGVjdCBhbGwgdG9rZW5zXG4gICAgICAgIGlmICghdGhpcy51aUNvbmYuaGFzVG9rZW4oKSkge1xuICAgICAgICAgICAgY29uc3QgbmV3U2VsOiBkMy5TZWxlY3Rpb248QmFzZVR5cGUsIGFueSwgQmFzZVR5cGUsIGFueT4gPSBkMy5zZWxlY3RBbGwoJy5zZWxlY3RlZC10b2tlbicpXG4gICAgICAgICAgICBpZiAoIW5ld1NlbC5lbXB0eSgpKSBuZXdTZWwuY2xhc3NlZCgnc2VsZWN0ZWQtdG9rZW4nLCBmYWxzZSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE90aGVyd2lzZSwgc2VsZWN0IHRoZSBpbmRpY2F0ZWQgdG9rZW5cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbjJTdHJpbmcgPSAoZTogdHAuVG9rZW5FdmVudCkgPT4gYCMke2Uuc2lkZX0tdG9rZW4tJHtlLmluZH1gXG4gICAgICAgICAgICBjb25zdCBuZXdTZWwgPSBkMy5zZWxlY3QodG9rZW4yU3RyaW5nKGUpKVxuICAgICAgICAgICAgLy8gQ2hlY2sgdGhhdCBzZWxlY3Rpb24gZXhpc3RzXG4gICAgICAgICAgICBpZiAoIW5ld1NlbC5lbXB0eSgpKSBuZXdTZWwuY2xhc3NlZCgnc2VsZWN0ZWQtdG9rZW4nLCB0cnVlKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIHByZXZpb3VzIHRva2VuIHNlbGVjdGlvbiwgaWYgYW55XG4gICAgICAgIGlmICghYWxyZWFkeVNlbGVjdGVkLmVtcHR5KCkpIHtcbiAgICAgICAgICAgIGFscmVhZHlTZWxlY3RlZC5jbGFzc2VkKCdzZWxlY3RlZC10b2tlbicsIGZhbHNlKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMudWlDb25mLm1vZGVsS2luZCgpID09IHRwLk1vZGVsS2luZC5BdXRvcmVncmVzc2l2ZSkge1xuICAgICAgICAgICAgdGhpcy5ncmF5VG9nZ2xlKCtlLmluZClcbiAgICAgICAgICAgIHRoaXMubWFya05leHRUb2dnbGUoK2UuaW5kLCB0aGlzLnRva0NhcHN1bGUuYS5sZW5ndGgoKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX3NlYXJjaERpc2FibGVyKClcbiAgICB9XG5cbiAgICAvKiogR3JheSBhbGwgdG9rZW5zIHRoYXQgaGF2ZSBpbmRleCBncmVhdGVyIHRoYW4gaW5kICovXG4gICAgcHJpdmF0ZSBncmF5QmFkVG9rcyhpbmQ6IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy51aUNvbmYubW9kZWxLaW5kKCkgPT0gdHAuTW9kZWxLaW5kLkF1dG9yZWdyZXNzaXZlKSB7XG4gICAgICAgICAgICBjb25zdCBncmF5VG9rcyA9IGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcyA9IGQzLnNlbGVjdCh0aGlzKVxuICAgICAgICAgICAgICAgIHMuY2xhc3NlZChcIm1hc2tlZC10b2tlblwiLCBpID4gaW5kKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZDMuc2VsZWN0QWxsKCcucmlnaHQtdG9rZW4nKS5lYWNoKGdyYXlUb2tzKVxuICAgICAgICAgICAgZDMuc2VsZWN0QWxsKCcubGVmdC10b2tlbicpLmVhY2goZ3JheVRva3MpXG4gICAgICAgIH1cbiAgICB9XG5cblxuICAgIHByaXZhdGUgZ3JheVRvZ2dsZShpbmQ6IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy51aUNvbmYuaGFzVG9rZW4oKSlcbiAgICAgICAgICAgIHRoaXMuZ3JheUJhZFRva3MoaW5kKVxuICAgICAgICBlbHNlXG4gICAgICAgICAgICBkMy5zZWxlY3RBbGwoJy50b2tlbicpLmNsYXNzZWQoJ21hc2tlZC10b2tlbicsIGZhbHNlKVxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtYXJrTmV4dFdvcmRUb2tzKGluZDogbnVtYmVyLCBOOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgbWFya1Rva3MgPSBmdW5jdGlvbiAoZCwgaSkge1xuICAgICAgICAgICAgY29uc3QgcyA9IGQzLnNlbGVjdCh0aGlzKVxuICAgICAgICAgICAgcy5jbGFzc2VkKFwibmV4dC10b2tlblwiLCBpID09IE1hdGgubWluKGluZCArIDEsIE4pKVxuICAgICAgICB9XG4gICAgICAgIGQzLnNlbGVjdEFsbCgnLnJpZ2h0LXRva2VuJykuZWFjaChtYXJrVG9rcylcbiAgICAgICAgZDMuc2VsZWN0QWxsKCcubGVmdC10b2tlbicpLmVhY2gobWFya1Rva3MpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtYXJrTmV4dFRvZ2dsZShpbmQ6IG51bWJlciwgTjogbnVtYmVyKSB7XG4gICAgICAgIGlmICh0aGlzLnVpQ29uZi5oYXNUb2tlbigpKVxuICAgICAgICAgICAgdGhpcy5tYXJrTmV4dFdvcmRUb2tzKGluZCwgTilcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgZDMuc2VsZWN0QWxsKCcudG9rZW4nKS5jbGFzc2VkKCduZXh0LXRva2VuJywgZmFsc2UpXG5cbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0TW9kZWxTZWxlY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzXG5cbiAgICAgICAgLy8gQmVsb3cgYXJlIHRoZSBhdmFpbGFibGUgbW9kZWxzLiBXaWxsIG5lZWQgdG8gY2hvb3NlIDMgdG8gYmUgYXZhaWxhYmxlIE9OTFlcbiAgICAgICAgY29uc3QgZGF0YSA9IFtcbiAgICAgICAgICAgIHsgbmFtZTogXCJiZXJ0LWJhc2UtY2FzZWRcIiwga2luZDogdHAuTW9kZWxLaW5kLkJpZGlyZWN0aW9uYWwgfSxcbiAgICAgICAgICAgIHsgbmFtZTogXCJiZXJ0LWJhc2UtdW5jYXNlZFwiLCBraW5kOiB0cC5Nb2RlbEtpbmQuQmlkaXJlY3Rpb25hbCB9LFxuICAgICAgICAgICAgeyBuYW1lOiBcImRpc3RpbGJlcnQtYmFzZS11bmNhc2VkXCIsIGtpbmQ6IHRwLk1vZGVsS2luZC5CaWRpcmVjdGlvbmFsIH0sXG4gICAgICAgICAgICB7IG5hbWU6IFwiZGlzdGlscm9iZXJ0YS1iYXNlXCIsIGtpbmQ6IHRwLk1vZGVsS2luZC5CaWRpcmVjdGlvbmFsIH0sXG4gICAgICAgICAgICAvLyB7IG5hbWU6IFwicm9iZXJ0YS1iYXNlXCIsIGtpbmQ6IHRwLk1vZGVsS2luZC5CaWRpcmVjdGlvbmFsIH0sXG4gICAgICAgICAgICB7IG5hbWU6IFwiZ3B0MlwiLCBraW5kOiB0cC5Nb2RlbEtpbmQuQXV0b3JlZ3Jlc3NpdmUgfSxcbiAgICAgICAgICAgIC8vIHsgbmFtZTogXCJncHQyLW1lZGl1bVwiLCBraW5kOiB0cC5Nb2RlbEtpbmQuQXV0b3JlZ3Jlc3NpdmUgfSxcbiAgICAgICAgICAgIC8vIHsgbmFtZTogXCJkaXN0aWxncHQyXCIsIGtpbmQ6IHRwLk1vZGVsS2luZC5BdXRvcmVncmVzc2l2ZSB9LFxuICAgICAgICBdXG5cbiAgICAgICAgY29uc3QgbmFtZXMgPSBSLm1hcChSLnByb3AoJ25hbWUnKSkoZGF0YSlcbiAgICAgICAgY29uc3Qga2luZHMgPSBSLm1hcChSLnByb3AoJ2tpbmQnKSkoZGF0YSlcbiAgICAgICAgY29uc3Qga2luZG1hcCA9IFIuemlwT2JqKG5hbWVzLCBraW5kcylcblxuICAgICAgICB0aGlzLnNlbHMubW9kZWxTZWxlY3Rvci5zZWxlY3RBbGwoJy5tb2RlbC1vcHRpb24nKVxuICAgICAgICAgICAgLmRhdGEoZGF0YSlcbiAgICAgICAgICAgIC5qb2luKCdvcHRpb24nKVxuICAgICAgICAgICAgLmNsYXNzZWQoJ21vZGVsLW9wdGlvbicsIHRydWUpXG4gICAgICAgICAgICAucHJvcGVydHkoJ3ZhbHVlJywgZCA9PiBkLm5hbWUpXG4gICAgICAgICAgICAuYXR0cihcIm1vZGVsa2luZFwiLCBkID0+IGQua2luZClcbiAgICAgICAgICAgIC50ZXh0KGQgPT4gZC5uYW1lKVxuXG4gICAgICAgIHRoaXMuc2Vscy5tb2RlbFNlbGVjdG9yLnByb3BlcnR5KCd2YWx1ZScsIHRoaXMudWlDb25mLm1vZGVsKCkpO1xuXG4gICAgICAgIHRoaXMuc2Vscy5tb2RlbFNlbGVjdG9yLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBtZSA9IGQzLnNlbGVjdCh0aGlzKVxuICAgICAgICAgICAgY29uc3QgbW5hbWUgPSBtZS5wcm9wZXJ0eSgndmFsdWUnKVxuICAgICAgICAgICAgc2VsZi51aUNvbmYubW9kZWwobW5hbWUpO1xuICAgICAgICAgICAgc2VsZi51aUNvbmYubW9kZWxLaW5kKGtpbmRtYXBbbW5hbWVdKTtcbiAgICAgICAgICAgIGlmIChraW5kbWFwW21uYW1lXSA9PSB0cC5Nb2RlbEtpbmQuQXV0b3JlZ3Jlc3NpdmUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIlJFU0VUVElORyBNQVNLIElORFNcIik7XG4gICAgICAgICAgICAgICAgc2VsZi51aUNvbmYubWFza0luZHMoW10pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLm1haW5Jbml0KCk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5pdENvcnB1c1NlbGVjdGlvbigpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IFtcbiAgICAgICAgICAgIHsgY29kZTogXCJ3b3pcIiwgZGlzcGxheTogXCJXaXphcmQgb2YgT3pcIiB9LFxuICAgICAgICAgICAgeyBjb2RlOiBcIndpa2lcIiwgZGlzcGxheTogXCJXaWtpcGVkaWFcIiB9LFxuICAgICAgICBdXG5cbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXNcbiAgICAgICAgc2VsZi5zZWxzLmNvcnB1c1NlbGVjdG9yLnNlbGVjdEFsbCgnb3B0aW9uJylcbiAgICAgICAgICAgIC5kYXRhKGRhdGEpXG4gICAgICAgICAgICAuam9pbignb3B0aW9uJylcbiAgICAgICAgICAgIC5wcm9wZXJ0eSgndmFsdWUnLCBkID0+IGQuY29kZSlcbiAgICAgICAgICAgIC50ZXh0KGQgPT4gZC5kaXNwbGF5KVxuXG4gICAgICAgIHRoaXMuc2Vscy5jb3JwdXNTZWxlY3Rvci5vbignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgbWUgPSBkMy5zZWxlY3QodGhpcylcbiAgICAgICAgICAgIHNlbGYudWlDb25mLmNvcnB1cyhtZS5wcm9wZXJ0eSgndmFsdWUnKSlcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHNlbGYudWlDb25mLmNvcnB1cygpKTtcbiAgICAgICAgfSlcblxuXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc3RhdGljSW5pdHMoKSB7XG4gICAgICAgIHRoaXMuX2luaXRTZW50ZW5jZUZvcm0oKTtcbiAgICAgICAgdGhpcy5faW5pdE1vZGVsU2VsZWN0aW9uKCk7XG4gICAgICAgIHRoaXMuX2luaXRDb3JwdXNTZWxlY3Rpb24oKTtcbiAgICAgICAgdGhpcy5faW5pdFF1ZXJ5Rm9ybSgpO1xuICAgICAgICB0aGlzLl9pbml0QWRkZXIoKTtcbiAgICAgICAgdGhpcy5fcmVuZGVySGVhZFN1bW1hcnkoKTtcbiAgICAgICAgdGhpcy5faW5pdE1ldGFTZWxlY3RvcnMoKTtcbiAgICAgICAgdGhpcy5faW5pdFRvZ2dsZSgpO1xuICAgICAgICB0aGlzLnJlbmRlckF0dEhlYWQoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJUb2tlbnMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0QWRkZXIoKSB7XG4gICAgICAgIGNvbnN0IHVwZGF0ZVVybE9mZnNldElkeHMgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnVpQ29uZi5vZmZzZXRJZHhzKHRoaXMudml6cy5jb3JwdXNNYXRNYW5hZ2VyLmlkeHMpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaXhDb3JwdXNNYXRIZWlnaHRzID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3V3JhcHBlZCA9IHRoaXMuX3dyYXBSZXN1bHRzKHRoaXMudml6cy5jb3JwdXNNYXRNYW5hZ2VyLmRhdGEoKSlcbiAgICAgICAgICAgIHRoaXMudml6cy5jb3JwdXNNYXRNYW5hZ2VyLmRhdGEobmV3V3JhcHBlZC5kYXRhKVxuICAgICAgICAgICAgdXBkYXRlVXJsT2Zmc2V0SWR4cygpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNlbHMuYnV0dG9ucy5hZGRSaWdodC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnZpenMuY29ycHVzTWF0TWFuYWdlci5hZGRSaWdodCgpXG4gICAgICAgICAgICB1cGRhdGVVcmxPZmZzZXRJZHhzKClcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLnNlbHMuYnV0dG9ucy5hZGRMZWZ0Lm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudml6cy5jb3JwdXNNYXRNYW5hZ2VyLmFkZExlZnQoKVxuICAgICAgICAgICAgdXBkYXRlVXJsT2Zmc2V0SWR4cygpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5zZWxzLmJ1dHRvbnMua2lsbFJpZ2h0Lm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudml6cy5jb3JwdXNNYXRNYW5hZ2VyLmtpbGxSaWdodCgpXG4gICAgICAgICAgICB1cGRhdGVVcmxPZmZzZXRJZHhzKClcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLnNlbHMuYnV0dG9ucy5raWxsTGVmdC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnZpenMuY29ycHVzTWF0TWFuYWdlci5raWxsTGVmdCgpXG4gICAgICAgICAgICB1cGRhdGVVcmxPZmZzZXRJZHhzKClcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLnNlbHMuYnV0dG9ucy5yZWZyZXNoLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIGZpeENvcnB1c01hdEhlaWdodHMoKTtcbiAgICAgICAgfSlcblxuICAgICAgICBjb25zdCBvbnJlc2l6ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNlbHMuY29ycHVzSW5zcGVjdG9yLnRleHQoKSAhPSAnJykgZml4Q29ycHVzTWF0SGVpZ2h0cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgd2luZG93Lm9ucmVzaXplID0gb25yZXNpemVcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0TWV0YVNlbGVjdG9ycygpIHtcbiAgICAgICAgdGhpcy5faW5pdE1hdGNoZWRXb3JkU2VsZWN0b3IodGhpcy5zZWxzLm1ldGFTZWxlY3Rvci5tYXRjaGVkV29yZClcbiAgICAgICAgdGhpcy5faW5pdE1heEF0dFNlbGVjdG9yKHRoaXMuc2Vscy5tZXRhU2VsZWN0b3IubWF4QXR0KVxuICAgIH1cblxuICAgIHByaXZhdGUgX2luaXRNYXhBdHRTZWxlY3RvcihzZWw6IEQzU2VsKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0IGNob29zZVNlbGVjdGVkID0gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtcyA9IHNlbC5zZWxlY3RBbGwoJ2xhYmVsJylcbiAgICAgICAgICAgIG1zLmNsYXNzZWQoJ2FjdGl2ZScsIGZhbHNlKVxuICAgICAgICAgICAgY29uc3QgZWwgPSBzZWwuc2VsZWN0QWxsKGBsYWJlbFt2YWx1ZT0ke3ZhbHVlfV1gKVxuICAgICAgICAgICAgZWwuY2xhc3NlZCgnYWN0aXZlJywgdHJ1ZSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNob29zZVNlbGVjdGVkKHRoaXMudWlDb25mLm1ldGFNYXgoKSlcblxuICAgICAgICBjb25zdCBlbCA9IHNlbC5zZWxlY3RBbGwoJ2xhYmVsJylcbiAgICAgICAgZWwub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgdmFsID0gPFNpbXBsZU1ldGE+ZDMuc2VsZWN0KHRoaXMpLmF0dHIoJ3ZhbHVlJyk7XG5cbiAgICAgICAgICAgIC8vIERvIHRvZ2dsZVxuICAgICAgICAgICAgc2VsLnNlbGVjdEFsbCgnLmFjdGl2ZScpLmNsYXNzZWQoJ2FjdGl2ZScsIGZhbHNlKVxuICAgICAgICAgICAgZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoJ2FjdGl2ZScsIHRydWUpXG4gICAgICAgICAgICBzZWxmLnVpQ29uZi5tZXRhTWF4KHZhbClcbiAgICAgICAgICAgIHNlbGYudml6cy5oaXN0b2dyYW1zLm1heEF0dC5tZXRhKHZhbClcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0TWF0Y2hlZFdvcmRTZWxlY3RvcihzZWw6IEQzU2VsKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0IGNob29zZVNlbGVjdGVkID0gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtcyA9IHNlbC5zZWxlY3RBbGwoJ2xhYmVsJylcbiAgICAgICAgICAgIG1zLmNsYXNzZWQoJ2FjdGl2ZScsIGZhbHNlKVxuICAgICAgICAgICAgY29uc3QgZWwgPSBzZWwuc2VsZWN0QWxsKGBsYWJlbFt2YWx1ZT0ke3ZhbHVlfV1gKVxuICAgICAgICAgICAgZWwuY2xhc3NlZCgnYWN0aXZlJywgdHJ1ZSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNob29zZVNlbGVjdGVkKHRoaXMudWlDb25mLm1ldGFNYXRjaCgpKVxuXG4gICAgICAgIGNvbnN0IGVsID0gc2VsLnNlbGVjdEFsbCgnbGFiZWwnKVxuICAgICAgICBlbC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwgPSA8U2ltcGxlTWV0YT5kMy5zZWxlY3QodGhpcykuYXR0cigndmFsdWUnKVxuXG4gICAgICAgICAgICAvLyBEbyB0b2dnbGVcbiAgICAgICAgICAgIHNlbC5zZWxlY3RBbGwoJy5hY3RpdmUnKS5jbGFzc2VkKCdhY3RpdmUnLCBmYWxzZSlcbiAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzKS5jbGFzc2VkKCdhY3RpdmUnLCB0cnVlKVxuICAgICAgICAgICAgc2VsZi51aUNvbmYubWV0YU1hdGNoKHZhbClcbiAgICAgICAgICAgIHNlbGYuX3VwZGF0ZUNvcnB1c0luc3BlY3RvckZyb21NZXRhKHZhbClcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcml2YXRlIF9kaXNhYmxlU2VhcmNoaW5nKGF0dHI6IGJvb2xlYW4pIHtcbiAgICAgICAgc2V0U2VsRGlzYWJsZWQoYXR0ciwgdGhpcy5zZWxzLmNvbnRleHRRdWVyeSlcbiAgICAgICAgc2V0U2VsRGlzYWJsZWQoYXR0ciwgdGhpcy5zZWxzLmVtYmVkZGluZ1F1ZXJ5KVxuICAgIH1cblxuICAgIHByaXZhdGUgX3VwZGF0ZUNvcnB1c0luc3BlY3RvckZyb21NZXRhKHZhbDogdHAuU2ltcGxlTWV0YSkge1xuICAgICAgICB0aGlzLnZpenMuY29ycHVzSW5zcGVjdG9yLnNob3dOZXh0KHRoaXMudWlDb25mLnNob3dOZXh0KVxuICAgICAgICB0aGlzLnZpenMuY29ycHVzTWF0TWFuYWdlci5waWNrKHZhbClcbiAgICAgICAgdGhpcy52aXpzLmhpc3RvZ3JhbXMubWF0Y2hlZFdvcmQubWV0YSh2YWwpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5pdFNlbnRlbmNlRm9ybSgpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgdGhpcy5zZWxzLmZvcm0uc2VudGVuY2VBLmF0dHIoJ3BsYWNlaG9sZGVyJywgXCJFbnRlciBuZXcgc2VudGVuY2UgdG8gYW5hbHl6ZVwiKVxuICAgICAgICB0aGlzLnNlbHMuZm9ybS5zZW50ZW5jZUEuYXR0cigndmFsdWUnLCB0aGlzLnVpQ29uZi5zZW50ZW5jZSgpKVxuXG4gICAgICAgIGNvbnN0IGNsZWFySW5zcGVjdG9yID0gKCkgPT4ge1xuICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c01hdE1hbmFnZXIuY2xlYXIoKTtcbiAgICAgICAgICAgIHNlbGYudml6cy5jb3JwdXNJbnNwZWN0b3IuY2xlYXIoKTtcbiAgICAgICAgICAgIHNlbGYudml6cy5oaXN0b2dyYW1zLm1hdGNoZWRXb3JkLmNsZWFyKCk7XG4gICAgICAgICAgICBzZWxmLnZpenMuaGlzdG9ncmFtcy5tYXhBdHQuY2xlYXIoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN1Ym1pdE5ld1NlbnRlbmNlID0gKCkgPT4ge1xuICAgICAgICAgICAgLy8gcmVwbGFjZSBhbGwgb2NjdXJlbmNlcyBvZiAnIycgaW4gc2VudGVuY2UgYXMgdGhpcyBjYXVzZXMgdGhlIEFQSSB0byBicmVha1xuICAgICAgICAgICAgY29uc3Qgc2VudGVuY2VfYTogc3RyaW5nID0gdGhpcy5zZWxzLmZvcm0uc2VudGVuY2VBLnByb3BlcnR5KFwidmFsdWVcIikucmVwbGFjZSgvXFwjL2csICcnKVxuXG4gICAgICAgICAgICAvLyBPbmx5IHVwZGF0ZSBpZiB0aGUgZm9ybSBpcyBmaWxsZWQgY29ycmVjdGx5XG4gICAgICAgICAgICBpZiAoc2VudGVuY2VfYS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbHMuYm9keS5zdHlsZShcImN1cnNvclwiLCBcInByb2dyZXNzXCIpXG4gICAgICAgICAgICAgICAgdGhpcy5hcGkuZ2V0TWV0YUF0dGVudGlvbnModGhpcy51aUNvbmYubW9kZWwoKSwgc2VudGVuY2VfYSwgdGhpcy51aUNvbmYubGF5ZXIoKSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKHJlc3A6IHJzcC5BdHRlbnRpb25EZXRhaWxzUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHIgPSByZXNwLnBheWxvYWRcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudWlDb25mLnNlbnRlbmNlKHNlbnRlbmNlX2EpXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVpQ29uZi5ybVRva2VuKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmF0dENhcHN1bGUudXBkYXRlRnJvbU5vcm1hbChyLCB0aGlzLnVpQ29uZi5oaWRlQ2xzU2VwKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy50b2tDYXBzdWxlLnVwZGF0ZUZyb21SZXNwb25zZShyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RvZ2dsZVRva2VuU2VsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJJbnNwZWN0b3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vscy5ib2R5LnN0eWxlKFwiY3Vyc29yXCIsIFwiZGVmYXVsdFwiKVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb25FbnRlciA9IFIuY3VycnkoKGtleUNvZGUsIGYsIGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlID0gZXZlbnQgfHwgd2luZG93LmV2ZW50O1xuICAgICAgICAgICAgaWYgKGUua2V5Q29kZSAhPT0ga2V5Q29kZSkgcmV0dXJuO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZigpO1xuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IG9uRW50ZXJTdWJtaXQgPSBvbkVudGVyKDEzLCBzdWJtaXROZXdTZW50ZW5jZSlcblxuICAgICAgICBjb25zdCBidG4gPSB0aGlzLnNlbHMuZm9ybS5idXR0b247XG4gICAgICAgIGNvbnN0IGlucHV0Qm94ID0gdGhpcy5zZWxzLmZvcm0uc2VudGVuY2VBO1xuXG4gICAgICAgIGJ0bi5vbihcImNsaWNrXCIsIHN1Ym1pdE5ld1NlbnRlbmNlKVxuICAgICAgICBpbnB1dEJveC5vbigna2V5cHJlc3MnLCBvbkVudGVyU3VibWl0KVxuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFNlYXJjaEVtYmVkcygpIHtcbiAgICAgICAgY29uc3Qgc2F2ZWRUb2tlbiA9IHRoaXMudWlDb25mLnRva2VuKCk7XG4gICAgICAgIGNvbnN0IG91dCA9IHRoaXMudml6cy50b2tlbnNbc2F2ZWRUb2tlbi5zaWRlXS5nZXRFbWJlZGRpbmcoc2F2ZWRUb2tlbi5pbmQpXG4gICAgICAgIHJldHVybiBvdXQuZW1iZWRkaW5nc1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFNlYXJjaENvbnRleHQoKSB7XG4gICAgICAgIGNvbnN0IHNhdmVkVG9rZW4gPSB0aGlzLnVpQ29uZi50b2tlbigpO1xuICAgICAgICBjb25zdCBvdXQgPSB0aGlzLnZpenMudG9rZW5zW3NhdmVkVG9rZW4uc2lkZV0uZ2V0RW1iZWRkaW5nKHNhdmVkVG9rZW4uaW5kKVxuICAgICAgICByZXR1cm4gb3V0LmNvbnRleHRzXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2VhcmNoRW1iZWRkaW5ncygpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiU0VBUkNISU5HIEVNQkVERElOR1NcIik7XG4gICAgICAgIGNvbnN0IGVtYmVkID0gdGhpcy5fZ2V0U2VhcmNoRW1iZWRzKClcbiAgICAgICAgY29uc3QgbGF5ZXIgPSBzZWxmLnVpQ29uZi5sYXllcigpXG4gICAgICAgIGNvbnN0IGhlYWRzID0gc2VsZi51aUNvbmYuaGVhZHMoKVxuICAgICAgICBjb25zdCBrID0gNTBcbiAgICAgICAgc2VsZi52aXpzLmNvcnB1c0luc3BlY3Rvci5zaG93TmV4dChzZWxmLnVpQ29uZi5zaG93TmV4dClcblxuICAgICAgICB0aGlzLnNlbHMuYm9keS5zdHlsZShcImN1cnNvclwiLCBcInByb2dyZXNzXCIpXG4gICAgICAgIHNlbGYuYXBpLmdldE5lYXJlc3RFbWJlZGRpbmdzKHNlbGYudWlDb25mLm1vZGVsKCksIHNlbGYudWlDb25mLmNvcnB1cygpLCBlbWJlZCwgbGF5ZXIsIGhlYWRzLCBrKVxuICAgICAgICAgICAgLnRoZW4oKHZhbDogcnNwLk5lYXJlc3ROZWlnaGJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbC5zdGF0dXMgPT0gNDA2KSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYubGVhdmVDb3JwdXNNc2coYEVtYmVkZGluZ3MgYXJlIG5vdCBhdmFpbGFibGUgZm9yIG1vZGVsICcke3NlbGYudWlDb25mLm1vZGVsKCl9JyBhbmQgY29ycHVzICcke3NlbGYudWlDb25mLmNvcnB1cygpfScgYXQgdGhpcyB0aW1lLmApXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ID0gdmFsLnBheWxvYWRcblxuICAgICAgICAgICAgICAgICAgICBzZWxmLnZpenMuY29ycHVzSW5zcGVjdG9yLnVuaGlkZVZpZXcoKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnZpenMuY29ycHVzTWF0TWFuYWdlci51bmhpZGVWaWV3KClcblxuICAgICAgICAgICAgICAgICAgICAvLyBHZXQgaGVpZ2h0cyBvZiBjb3JwdXMgaW5zcGVjdG9yIHJvd3MuXG4gICAgICAgICAgICAgICAgICAgIHNlbGYudml6cy5jb3JwdXNJbnNwZWN0b3IudXBkYXRlKHYpXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRWYWxzID0gc2VsZi5fd3JhcFJlc3VsdHModilcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY291bnRlZFZhbHMgPSB3cmFwcGVkVmFscy5nZXRNYXRjaGVkSGlzdG9ncmFtKClcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0VmFscyA9IHdyYXBwZWRWYWxzLmdldE1heEF0dEhpc3RvZ3JhbSgpXG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c01hdE1hbmFnZXIudXBkYXRlKHdyYXBwZWRWYWxzLmRhdGEpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2Vscy5oaXN0b2dyYW1zLm1hdGNoZWRXb3JkRGVzY3JpcHRpb24udGV4dCh0aGlzLnVpQ29uZi5tYXRjaEhpc3RvZ3JhbURlc2NyaXB0aW9uKVxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIk1BVENIRVI6IFwiLCBzZWxmLnNlbHMuaGlzdG9ncmFtcy5tYXRjaGVkV29yZCk7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYudml6cy5oaXN0b2dyYW1zLm1hdGNoZWRXb3JkLnVwZGF0ZShjb3VudGVkVmFscylcbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmhpc3RvZ3JhbXMubWF4QXR0LnVwZGF0ZShvZmZzZXRWYWxzKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnVpQ29uZi5kaXNwbGF5SW5zcGVjdG9yKCdlbWJlZGRpbmdzJylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlQ29ycHVzSW5zcGVjdG9yRnJvbU1ldGEodGhpcy51aUNvbmYubWV0YU1hdGNoKCkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2Vscy5ib2R5LnN0eWxlKFwiY3Vyc29yXCIsIFwiZGVmYXVsdFwiKVxuICAgICAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZWFyY2hDb250ZXh0KCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgY29uc29sZS5sb2coXCJTRUFSQ0hJTkcgQ09OVEVYVFNcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9nZXRTZWFyY2hDb250ZXh0KClcbiAgICAgICAgY29uc3QgbGF5ZXIgPSBzZWxmLnVpQ29uZi5sYXllcigpXG4gICAgICAgIGNvbnN0IGhlYWRzID0gc2VsZi51aUNvbmYuaGVhZHMoKVxuICAgICAgICBjb25zdCBrID0gNTBcbiAgICAgICAgc2VsZi52aXpzLmNvcnB1c0luc3BlY3Rvci5zaG93TmV4dChzZWxmLnVpQ29uZi5zaG93TmV4dClcblxuICAgICAgICB0aGlzLnNlbHMuYm9keS5zdHlsZShcImN1cnNvclwiLCBcInByb2dyZXNzXCIpXG5cbiAgICAgICAgc2VsZi5hcGkuZ2V0TmVhcmVzdENvbnRleHRzKHNlbGYudWlDb25mLm1vZGVsKCksIHNlbGYudWlDb25mLmNvcnB1cygpLCBjb250ZXh0LCBsYXllciwgaGVhZHMsIGspXG4gICAgICAgICAgICAudGhlbigodmFsOiByc3AuTmVhcmVzdE5laWdoYm9yUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBHZXQgaGVpZ2h0cyBvZiBjb3JwdXMgaW5zcGVjdG9yIHJvd3MuXG4gICAgICAgICAgICAgICAgaWYgKHZhbC5zdGF0dXMgPT0gNDA2KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ29udGV4dHMgYXJlIG5vdCBhdmFpbGFibGUhXCIpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmxlYXZlQ29ycHVzTXNnKGBDb250ZXh0cyBhcmUgbm90IGF2YWlsYWJsZSBmb3IgbW9kZWwgJyR7c2VsZi51aUNvbmYubW9kZWwoKX0nIGFuZCBjb3JwdXMgJyR7c2VsZi51aUNvbmYuY29ycHVzKCl9JyBhdCB0aGlzIHRpbWUuYClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHYgPSB2YWwucGF5bG9hZDtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJISURJTkdcIik7XG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c0luc3BlY3Rvci51cGRhdGUodilcblxuICAgICAgICAgICAgICAgICAgICBTZWwuaGlkZUVsZW1lbnQoc2VsZi5zZWxzLmNvcnB1c01zZ0JveClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c0luc3BlY3Rvci51bmhpZGVWaWV3KClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c01hdE1hbmFnZXIudW5oaWRlVmlldygpXG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFZhbHMgPSBzZWxmLl93cmFwUmVzdWx0cyh2KVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3VudGVkVmFscyA9IHdyYXBwZWRWYWxzLmdldE1hdGNoZWRIaXN0b2dyYW0oKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXRWYWxzID0gd3JhcHBlZFZhbHMuZ2V0TWF4QXR0SGlzdG9ncmFtKClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmNvcnB1c01hdE1hbmFnZXIudXBkYXRlKHdyYXBwZWRWYWxzLmRhdGEpXG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXpzLmhpc3RvZ3JhbXMubWF0Y2hlZFdvcmQudXBkYXRlKGNvdW50ZWRWYWxzKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnZpenMuaGlzdG9ncmFtcy5tYXhBdHQudXBkYXRlKG9mZnNldFZhbHMpXG5cbiAgICAgICAgICAgICAgICAgICAgc2VsZi51aUNvbmYuZGlzcGxheUluc3BlY3RvcignY29udGV4dCcpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUNvcnB1c0luc3BlY3RvckZyb21NZXRhKHRoaXMudWlDb25mLm1ldGFNYXRjaCgpKVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnZpenMuaGlzdG9ncmFtcy5tYXhBdHQubWV0YShzZWxmLnVpQ29uZi5tZXRhTWF4KCkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2Vscy5ib2R5LnN0eWxlKFwiY3Vyc29yXCIsIFwiZGVmYXVsdFwiKVxuICAgICAgICAgICAgfSlcbiAgICB9XG5cbiAgICBwcml2YXRlIF9xdWVyeUNvbnRleHQoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLnVpQ29uZi5oYXNUb2tlbigpKSB7XG4gICAgICAgICAgICB0aGlzLl9zZWFyY2hDb250ZXh0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIldhcyB0b2xkIHRvIHNob3cgaW5zcGVjdG9yIGJ1dCB3YXMgbm90IGdpdmVuIGEgc2VsZWN0ZWQgdG9rZW4gZW1iZWRkaW5nXCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9xdWVyeUVtYmVkZGluZ3MoKSB7XG4gICAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLnVpQ29uZi5oYXNUb2tlbigpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcInRva2VuOiBcIiwgdGhpcy51aUNvbmYudG9rZW4oKSk7XG4gICAgICAgICAgICB0aGlzLl9zZWFyY2hFbWJlZGRpbmdzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcIldhcyB0b2xkIHRvIHNob3cgaW5zcGVjdG9yIGJ1dCB3YXMgbm90IGdpdmVuIGEgc2VsZWN0ZWQgdG9rZW4gZW1iZWRkaW5nXCIpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIF9zZWFyY2hpbmdEaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnVpQ29uZi5oZWFkcygpLmxlbmd0aCA9PSAwKSB8fCAoIXRoaXMudWlDb25mLmhhc1Rva2VuKCkpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2VhcmNoRGlzYWJsZXIoKSB7XG4gICAgICAgIHRoaXMuX2Rpc2FibGVTZWFyY2hpbmcodGhpcy5fc2VhcmNoaW5nRGlzYWJsZWQoKSlcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0UXVlcnlGb3JtKCkge1xuICAgICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgICAgdGhpcy5fc2VhcmNoRGlzYWJsZXIoKVxuXG4gICAgICAgIHRoaXMuc2Vscy5jb250ZXh0UXVlcnkub24oXCJjbGlja1wiLCAoKSA9PiB7XG4gICAgICAgICAgICBzZWxmLl9xdWVyeUNvbnRleHQoKVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuc2Vscy5lbWJlZGRpbmdRdWVyeS5vbihcImNsaWNrXCIsICgpID0+IHtcbiAgICAgICAgICAgIHNlbGYuX3F1ZXJ5RW1iZWRkaW5ncygpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfcmVuZGVySGVhZFN1bW1hcnkoKSB7XG4gICAgICAgIHRoaXMuc2Vscy5zZWxlY3RlZEhlYWRzXG4gICAgICAgICAgICAuaHRtbChSLmpvaW4oJywgJywgdGhpcy51aUNvbmYuaGVhZHMoKS5tYXAoaCA9PiBoICsgMSkpKVxuICAgIH1cblxuICAgIC8vIE1vZGlmeSBmYWlzcyByZXN1bHRzIHdpdGggY29ycmVzcG9uZGluZyBoZWlnaHRzXG4gICAgcHJpdmF0ZSBfd3JhcFJlc3VsdHMocmV0dXJuZWRGYWlzc1Jlc3VsdHM6IHRwLkZhaXNzU2VhcmNoUmVzdWx0c1tdKSB7XG5cbiAgICAgICAgY29uc3Qgcm93cyA9IGQzLnNlbGVjdEFsbCgnLmluc3BlY3Rvci1yb3cnKVxuXG4gICAgICAgIC8vIERvbid0IGp1c3QgdXNlIG9mZnNldEhlaWdodCBzaW5jZSB0aGF0IHJvdW5kcyB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyXG4gICAgICAgIGNvbnN0IGhlaWdodHMgPSByb3dzLm5vZGVzKCkubWFwKChuOiBIVE1MRWxlbWVudCkgPT4gbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHQpXG5cbiAgICAgICAgY29uc3QgbmV3VmFscyA9IHJldHVybmVkRmFpc3NSZXN1bHRzLm1hcCgodiwgaSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFIuYXNzb2MoJ2hlaWdodCcsIGhlaWdodHNbaV0sIHYpXG4gICAgICAgIH0pXG5cbiAgICAgICAgY29uc3Qgd3JhcHBlZFZhbHMgPSBuZXcgRmFpc3NTZWFyY2hSZXN1bHRXcmFwcGVyKG5ld1ZhbHMsIHRoaXMudWlDb25mLnNob3dOZXh0KVxuXG4gICAgICAgIHJldHVybiB3cmFwcGVkVmFsc1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdExheWVycyhuTGF5ZXJzOiBudW1iZXIpIHtcbiAgICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICAgIGxldCBoYXNBY3RpdmUgPSBmYWxzZTtcblxuICAgICAgICBjb25zdCBjaGVja2JveGVzID0gc2VsZi5zZWxzLmxheWVyQ2hlY2tib3hlcy5zZWxlY3RBbGwoXCIubGF5ZXJDaGVja2JveFwiKVxuICAgICAgICAgICAgLmRhdGEoXy5yYW5nZSgwLCBuTGF5ZXJzKSlcbiAgICAgICAgICAgIC5qb2luKFwibGFiZWxcIilcbiAgICAgICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJidG4gYnV0dG9uIGxheWVyQ2hlY2tib3hcIilcbiAgICAgICAgICAgIC5jbGFzc2VkKCdhY3RpdmUnLCAoZCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEFzc2lnbiB0byBsYXJnZXN0IGxheWVyIGF2YWlsYWJsZSBpZiB1aUNvbmYubGF5ZXIoKSA+IG5ldyBuTGF5ZXJzXG4gICAgICAgICAgICAgICAgaWYgKGQgPT0gc2VsZi51aUNvbmYubGF5ZXIoKSkgeyAvLyBKYXZhc2NyaXB0IGlzIDAgaW5kZXhlZCFcbiAgICAgICAgICAgICAgICAgICAgaGFzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWhhc0FjdGl2ZSAmJiBkID09IG5MYXllcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi51aUNvbmYubGF5ZXIoZClcbiAgICAgICAgICAgICAgICAgICAgaGFzQWN0aXZlID0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRleHQoKGQpID0+IGQgKyAxKVxuICAgICAgICAgICAgLmFwcGVuZChcImlucHV0XCIpXG4gICAgICAgICAgICAuYXR0cihcInR5cGVcIiwgXCJyYWRpb1wiKVxuICAgICAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBcImNoZWNrYm94LWlubGluZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJuYW1lXCIsIFwibGF5ZXJib3hcIilcbiAgICAgICAgICAgIC8vIC5hdHRyKFwiaGVhZFwiLCBkID0+IGQpXG4gICAgICAgICAgICAuYXR0cihcImlkXCIsIChkLCBpKSA9PiBcImxheWVyQ2hlY2tib3hcIiArIGkpXG4gICAgICAgIC8vIC50ZXh0KChkLCBpKSA9PiBkICsgXCIgXCIpXG5cbiAgICAgICAgZnJvbUV2ZW50KGNoZWNrYm94ZXMubm9kZXMoKSwgJ2NoYW5nZScpLnBpcGUoXG4gICAgICAgICAgICB0YXAoKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlEYXRhID0gZDMuc2VsZWN0KDxCYXNlVHlwZT5lLnRhcmdldCkuZGF0dW0oKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhteURhdGEsIFwiLS0tIG15RGF0YVwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbHMubGF5ZXJDaGVja2JveGVzLnNlbGVjdEFsbChcIi5sYXllckNoZWNrYm94XCIpXG4gICAgICAgICAgICAgICAgICAgIC5jbGFzc2VkKCdhY3RpdmUnLCBkID0+IGQgPT09IG15RGF0YSlcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbWFwKCh2OiBFdmVudCkgPT4gK2QzLnNlbGVjdCg8QmFzZVR5cGU+di50YXJnZXQpLmRhdHVtKCkpLFxuICAgICAgICAgICAgdGFwKHYgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiTmV3IGxheWVyOiBcIiwgdik7XG4gICAgICAgICAgICAgICAgc2VsZi51aUNvbmYubGF5ZXIodik7XG4gICAgICAgICAgICAgICAgc2VsZi5zZWxzLmJvZHkuc3R5bGUoXCJjdXJzb3JcIiwgXCJwcm9ncmVzc1wiKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc3dpdGNoTWFwKCh2KSA9PiBmcm9tKHNlbGYuYXBpLnVwZGF0ZU1hc2tlZEF0dGVudGlvbnMoc2VsZi51aUNvbmYubW9kZWwoKSwgc2VsZi50b2tDYXBzdWxlLmEsIHNlbGYudWlDb25mLnNlbnRlbmNlKCksIHYpKSlcbiAgICAgICAgKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogKHJlc3A6IHJzcC5BdHRlbnRpb25EZXRhaWxzUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCByID0gcmVzcC5wYXlsb2FkO1xuICAgICAgICAgICAgICAgIHNlbGYuYXR0Q2Fwc3VsZS51cGRhdGVGcm9tTm9ybWFsKHIsIHRoaXMudWlDb25mLmhpZGVDbHNTZXAoKSk7XG4gICAgICAgICAgICAgICAgc2VsZi50b2tDYXBzdWxlLnVwZGF0ZVRva2VucyhyKTtcbiAgICAgICAgICAgICAgICBzZWxmLnVpQ29uZi5tYXNrSW5kcyhzZWxmLnRva0NhcHN1bGUuYS5tYXNrSW5kcylcbiAgICAgICAgICAgICAgICBzZWxmLnVwZGF0ZSgpO1xuICAgICAgICAgICAgICAgIHNlbGYuc2Vscy5ib2R5LnN0eWxlKFwiY3Vyc29yXCIsIFwiZGVmYXVsdFwiKVxuICAgICAgICAgICAgICAgIHNlbGYuX3RvZ2dsZVRva2VuU2VsKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgY29uc3QgbGF5ZXJJZCA9IGAjbGF5ZXJDaGVja2JveCR7dGhpcy51aUNvbmYubGF5ZXIoKX1gXG4gICAgICAgIGNvbnNvbGUubG9nKFwiTGF5ZXIgSUQ6IFwiLCBsYXllcklkKTtcbiAgICAgICAgZDMuc2VsZWN0KGxheWVySWQpLmF0dHIoXCJjaGVja2VkXCIsIFwiY2hlY2tlZFwiKVxuXG4gICAgICAgIC8vIEluaXQgdGhyZXNob2xkIHN0dWZmXG4gICAgICAgIGNvbnN0IGRpc3BUaHJlc2ggPSAodGhyZXNoKSA9PiBNYXRoLnJvdW5kKHRocmVzaCAqIDEwMClcbiAgICAgICAgZDMuc2VsZWN0KCcjbXktcmFuZ2UtdmFsdWUnKS50ZXh0KGRpc3BUaHJlc2goc2VsZi51aUNvbmYudGhyZXNob2xkKCkpKVxuXG4gICAgICAgIHRoaXMuc2Vscy50aHJlc2hTbGlkZXIub24oXCJpbnB1dFwiLCBfLnRocm90dGxlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSA8SFRNTElucHV0RWxlbWVudD50aGlzO1xuICAgICAgICAgICAgc2VsZi51aUNvbmYudGhyZXNob2xkKCtub2RlLnZhbHVlIC8gMTAwKTtcbiAgICAgICAgICAgIGQzLnNlbGVjdCgnI215LXJhbmdlLXZhbHVlJykudGV4dChkaXNwVGhyZXNoKHNlbGYudWlDb25mLnRocmVzaG9sZCgpKSlcbiAgICAgICAgICAgIHNlbGYudml6cy5hdHRlbnRpb25TdmcudGhyZXNob2xkKHNlbGYudWlDb25mLnRocmVzaG9sZCgpKVxuICAgICAgICB9LCAxMDApKVxuXG4gICAgICAgIHRoaXMuc2Vscy5oZWFkU2VsZWN0QWxsLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2VsZi51aUNvbmYuc2VsZWN0QWxsSGVhZHMoKTtcbiAgICAgICAgICAgIHNlbGYuX3NlYXJjaERpc2FibGVyKClcbiAgICAgICAgICAgIHNlbGYucmVuZGVyU3ZnKClcbiAgICAgICAgICAgIHNlbGYucmVuZGVyQXR0SGVhZCgpXG4gICAgICAgIH0pXG5cbiAgICAgICAgdGhpcy5zZWxzLmhlYWRTZWxlY3ROb25lLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2VsZi51aUNvbmYuc2VsZWN0Tm9IZWFkcygpO1xuICAgICAgICAgICAgc2VsZi5fc2VhcmNoRGlzYWJsZXIoKTtcbiAgICAgICAgICAgIHNlbGYucmVuZGVyU3ZnKClcbiAgICAgICAgICAgIHNlbGYucmVuZGVyQXR0SGVhZCgpXG4gICAgICAgICAgICBTZWwuc2V0SGlkZGVuKFwiLmF0bi1jdXJ2ZVwiKVxuICAgICAgICB9KVxuXG4gICAgfVxuXG4gICAgX2luaXRUb2dnbGUoKSB7XG4gICAgICAgIGZyb21FdmVudCh0aGlzLnNlbHMuY2xzVG9nZ2xlLm5vZGUoKSwgJ2lucHV0JykucGlwZShcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgLS0gVE9ETzogRklYICFcbiAgICAgICAgICAgIG1hcChlID0+IGUuc3JjRWxlbWVudC5jaGVja2VkKSxcbiAgICAgICAgKS5zdWJzY3JpYmUoe1xuICAgICAgICAgICAgbmV4dDogdiA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51aUNvbmYuaGlkZUNsc1NlcCh2KVxuICAgICAgICAgICAgICAgIHRoaXMuYXR0Q2Fwc3VsZS56ZXJvZWQodilcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlclN2ZygpO1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyQXR0SGVhZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgIH1cblxuICAgIHJlbmRlckF0dEhlYWQoKSB7XG4gICAgICAgIGNvbnN0IGhlYWRzID0gXy5yYW5nZSgwLCB0aGlzLnVpQ29uZi5fbkhlYWRzKVxuICAgICAgICBjb25zdCBmb2N1c0F0dCA9IHRoaXMuYXR0Q2Fwc3VsZS5hdHRcbiAgICAgICAgY29uc3QgdG9rZW4gPSB0aGlzLnVpQ29uZi5oYXNUb2tlbigpID8gdGhpcy51aUNvbmYudG9rZW4oKSA6IG51bGxcbiAgICAgICAgLy9AdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IGxlZnRBdHRJbmZvID0gZ2V0QXR0ZW50aW9uSW5mbyhmb2N1c0F0dCwgaGVhZHMsIFwibGVmdFwiLCB0b2tlbik7XG4gICAgICAgIC8vQHRzLWlnbm9yZVxuICAgICAgICBjb25zdCByaWdodEF0dEluZm8gPSBnZXRBdHRlbnRpb25JbmZvKGZvY3VzQXR0LCBoZWFkcywgXCJyaWdodFwiLCB0b2tlbik7XG4gICAgICAgIHRoaXMudml6cy5sZWZ0SGVhZHMub3B0aW9ucy5vZmZzZXQgPSB0aGlzLnVpQ29uZi5vZmZzZXRcbiAgICAgICAgdGhpcy52aXpzLmxlZnRIZWFkcy51cGRhdGUobGVmdEF0dEluZm8pXG4gICAgICAgIHRoaXMudml6cy5yaWdodEhlYWRzLnVwZGF0ZShyaWdodEF0dEluZm8pXG4gICAgICAgIHRoaXMuX3JlbmRlckhlYWRTdW1tYXJ5KCk7XG5cbiAgICAgICAgLy8gTWFrZSBzdXJlXG4gICAgICAgIGhlYWRzLmZvckVhY2goKGgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnVpQ29uZi5oZWFkU2V0KCkuaGFzKGgpKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0SGVhZChoKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB1bnNlbGVjdEhlYWQoaClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9O1xuXG4gICAgcmVuZGVyVG9rZW5zKCkge1xuICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy50b2tDYXBzdWxlW3RoaXMudWlDb25mLmF0dFR5cGVbMF1dXG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy50b2tDYXBzdWxlW3RoaXMudWlDb25mLmF0dFR5cGVbMV1dXG5cbiAgICAgICAgY29uc29sZS5sb2coXCJub3c6IFwiLCB0aGlzLnVpQ29uZi5vZmZzZXQpO1xuICAgICAgICB0aGlzLnZpenMudG9rZW5zLmxlZnQub3B0aW9ucy5vZmZzZXQgPSB0aGlzLnVpQ29uZi5vZmZzZXRcbiAgICAgICAgdGhpcy52aXpzLnRva2Vucy5sZWZ0LnVwZGF0ZShsZWZ0LnRva2VuRGF0YSk7XG4gICAgICAgIHRoaXMudml6cy50b2tlbnMubGVmdC5tYXNrKGxlZnQubWFza0luZHMpO1xuICAgICAgICB0aGlzLnZpenMudG9rZW5zLnJpZ2h0LnVwZGF0ZShyaWdodC50b2tlbkRhdGEpO1xuICAgICAgICB0aGlzLnZpenMudG9rZW5zLnJpZ2h0Lm1hc2socmlnaHQubWFza0luZHMpO1xuICAgICAgICAvLyBkaXNwbGF5U2VsZWN0ZWRUb2tlblxuICAgIH1cblxuICAgIHJlbmRlclN2ZygpIHtcbiAgICAgICAgY29uc3QgYXR0ID0gdGhpcy5hdHRDYXBzdWxlLmJ5SGVhZHModGhpcy51aUNvbmYuaGVhZHMoKSlcbiAgICAgICAgdGhpcy52aXpzLmF0dGVudGlvblN2Zy5vcHRpb25zLm9mZnNldCA9IHRoaXMudWlDb25mLm9mZnNldFxuICAgICAgICBjb25zdCBzdmcgPSA8QXR0ZW50aW9uR3JhcGg+dGhpcy52aXpzLmF0dGVudGlvblN2Zy5kYXRhKGF0dCk7XG4gICAgICAgIHN2Zy51cGRhdGUoYXR0KVxuICAgICAgICBjb25zdCBtYXhUb2tlbnMgPSBfLm1heChbdGhpcy50b2tDYXBzdWxlLmEubGVuZ3RoKCldKVxuICAgICAgICBjb25zdCBuZXdIZWlnaHQgPSBzdmcub3B0aW9ucy5ib3hoZWlnaHQgKiBtYXhUb2tlbnNcbiAgICAgICAgc3ZnLmhlaWdodChuZXdIZWlnaHQpXG5cbiAgICAgICAgLy8gRG9uJ3QgcmVkaXNwbGF5IGV2ZXJ5dGhpbmcgaWYgb25lIHRva2VuIGlzIHNlbGVjdGVkXG4gICAgICAgIHNob3dCeVNpZGUodGhpcy51aUNvbmYudG9rZW4oKSlcbiAgICB9O1xuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICB0aGlzLnJlbmRlclRva2VucygpO1xuICAgICAgICB0aGlzLnJlbmRlclN2ZygpO1xuICAgICAgICB0aGlzLnJlbmRlckF0dEhlYWQoKTtcbiAgICB9XG5cbiAgICB1cGRhdGUoKSB7XG4gICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfVxufVxuIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIiwiLyogKGlnbm9yZWQpICovIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/client/dist/vendor.js b/client/dist/vendor.js new file mode 100644 index 0000000000000000000000000000000000000000..57b0bf21acdf611ed02bd69fadc0d41c9786a70e --- /dev/null +++ b/client/dist/vendor.js @@ -0,0 +1,78835 @@ +(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["vendor"],{ + +/***/ "./node_modules/@tensorflow/tfjs-converter/dist/tf-converter.esm.js": +/*!**************************************************************************!*\ + !*** ./node_modules/@tensorflow/tfjs-converter/dist/tf-converter.esm.js ***! + \**************************************************************************/ +/*! exports provided: GraphModel, loadGraphModel, deregisterOp, registerOp, version_converter */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* WEBPACK VAR INJECTION */(function(Buffer) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GraphModel", function() { return GraphModel; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "loadGraphModel", function() { return loadGraphModel; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deregisterOp", function() { return deregisterOp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerOp", function() { return registerOp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "version_converter", function() { return version; }); +/* harmony import */ var _tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tensorflow/tfjs-core */ "./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js"); +/** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ +var DataType,SaverDef,__assign=function(){return(__assign=Object.assign||function(e){for(var t,a=1,r=arguments.length;a0&&n[n.length-1])&&(6===s[0]||2===s[0])){o=0;continue}if(3===s[0]&&(!n||s[1]>n[0]&&s[1]=this.tensors.length)throw new Error("Tried to read from index "+e+", but array size is: "+this.tensors.length);var t=this.tensors[e];if(t.cleared)throw new Error("TensorArray "+this.name+": Could not read index "+e+" twice because it was cleared after a previous read (perhaps try setting clear_after_read = false?).");return this.clearAfterRead&&(t.cleared=!0),t.read=!0,t.tensor},e.prototype.readMany=function(e){var t=this;return e.map(function(e){return t.read(e)})},e.prototype.write=function(e,t){if(this.closed_)throw new Error("TensorArray "+this.name+" has already been closed.");if(e<0||!this.dynamicSize&&e>=this.maxSize)throw new Error("Tried to write to index "+e+", but array is not resizeable and size is: "+this.maxSize);var a=this.tensors[e]||{};if(t.dtype!==this.dtype)throw new Error("TensorArray "+this.name+": Could not write to TensorArray index "+e+",\n because the value dtype is "+t.dtype+", but TensorArray dtype is "+this.dtype+".");if(0!==this.size()||null!=this.elementShape&&0!==this.elementShape.length||(this.elementShape=t.shape),this.assertShapesMatchAllowUndefinedSize(this.elementShape,t.shape,"TensorArray "+this.name+": Could not write to TensorArray index "+e+"."),a&&a.read)throw new Error("TensorArray "+this.name+": Could not write to TensorArray index "+e+", because it has already been read.");if(a&&a.written)throw new Error("TensorArray "+this.name+": Could not write to TensorArray index "+e+", because it has already been written.");a.tensor=t,a.written=!0,this.tensors[e]=a},e.prototype.writeMany=function(e,t){var a=this;if(e.length!==t.length)throw new Error("TensorArray "+this.name+": could not write multiple tensors,because the index size: "+e.length+" is not the same as tensors size: "+t.length+".");e.forEach(function(e,r){return a.write(e,t[r])})},e.prototype.gather=function(e,t){if(t&&t!==this.dtype)throw new Error("TensorArray dtype is "+this.dtype+" but gather requested dtype "+t);if(!e){e=[];for(var a=0;a=this.maxSize)throw new Error("Max index must be < array size ("+a+" vs. "+this.maxSize+")");this.writeMany(e,Object(_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["unstack"])(t,0))},e.prototype.split=function(e,t){var a=this;if(t.dtype!==this.dtype)throw new Error("TensorArray dtype is "+this.dtype+" but tensor has dtype "+t.dtype);var r=0,n=e.map(function(e){return r+=e});if(r!==t.shape[0])throw new Error("Expected sum of lengths to be equal to\n tensor.shape[0], but sum of lengths is\n "+r+", and tensor's shape is: "+t.shape);if(!this.dynamicSize&&e.length!==this.maxSize)throw new Error("TensorArray's size is not equal to the size of lengths ("+this.maxSize+" vs. "+e.length+"), and the TensorArray is not marked as dynamically resizeable");var s=0===r?0:t.size/r,o=[];Object(_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["tidy"])(function(){t=t.reshape([1,r,s]);for(var p=0;p1)for(var h=1;h1))throw new Error("Cannot exit frame, the context is empty");this.contexts=this.contexts.slice(),this.contexts.splice(-1),this.currentContextIds.shift()},e.prototype.nextIteration=function(){if(!(this.contexts&&this.contexts.length>0))throw new Error("Cannot increase frame iteration, the context is empty");this.contexts=this.contexts.slice(),this.lastId++;var e=Object.assign({},this.contexts[this.contexts.length-1]);e.iterationId+=1,e.id=this.lastId,this.contexts.splice(-1,1,e),this._currentContextIds.splice(0,1,this.contextIdforContexts(this.contexts))},e.prototype.getWeight=function(e){return this.weightMap[e]},e.prototype.addTensorArray=function(e){this.tensorArrayMap[e.id]=e},e.prototype.getTensorArray=function(e){return this.tensorArrayMap[e]},e}();function getExecutionSubgraph(e,t,a){for(var r=new Set,n=[],s=null,o=null,p=new Set,u=t.slice();u.length>0;){var i=u.pop();(isControlFlow(i)||isDynamicShape(i))&&null==s&&(o=(s=i).children.map(function(e){return e.name}).filter(function(e){return r.has(e)})),r.add(i.name),null==a[i.name]&&(null==e[i.name]&&(0!==i.inputs.length?i.inputs.forEach(function(e){p.has(e.name)||(p.add(e.name),u.push(e))}):n.push(i.name)))}return{inputs:e,outputs:t,usedNodes:r,missingInputs:n,dynamicNode:s,syncInputs:o}}function getNodesInTopologicalOrder(e,t,a){var r=a.usedNodes,n=a.inputs,s=[];Object.keys(n).map(function(t){return e.nodes[t]}).forEach(function(e){r.has(e.name)&&s.push(e)}),e.weights.forEach(function(e){r.has(e.name)&&s.push(e)});for(var o=new Set,p=[];s.length>0;){var u=s.pop();o.add(u.name),t[u.name]||p.push(u),u.children.forEach(function(e){!o.has(e.name)&&r.has(e.name)&&e.inputs.every(function(e){return o.has(e.name)})&&s.push(e)})}return p}var CONTROL_FLOW_OPS=["Switch","Merge","Enter","Exit","NextIteration"],DYNAMIC_SHAPE_OPS=["NonMaxSuppressionV2","NonMaxSuppressionV3","Where"];function isControlFlow(e){return CONTROL_FLOW_OPS.indexOf(e.op)>=0}function isDynamicShape(e){return DYNAMIC_SHAPE_OPS.indexOf(e.op)>=0}var GraphExecutor=function(){function e(e){this.graph=e,this.compiledMap=new Map,this._weightMap={},this.SEPERATOR=",",this.placeholders=e.placeholders,this._outputs=e.outputs}return Object.defineProperty(e.prototype,"weightMap",{get:function(){return this._weightMap},set:function(e){var t=Object.keys(e).map(function(t){return e[t].map(function(e){return e.id})});this.weightIds=[].concat.apply([],t),this._weightMap=e},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"inputs",{get:function(){return this.placeholders.map(function(e){return{name:e.name,shape:e.attrParams.shape?e.attrParams.shape.value:void 0,dtype:e.attrParams.dtype?e.attrParams.dtype.value:void 0}})},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputs",{get:function(){return this._outputs.map(function(e){return{name:e.name,shape:e.attrParams.shape?e.attrParams.shape.value:void 0,dtype:e.attrParams.dtype?e.attrParams.dtype.value:void 0}})},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"inputNodes",{get:function(){return this.placeholders.map(function(e){return e.name})},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputNodes",{get:function(){return this.outputs.map(function(e){return e.name})},enumerable:!0,configurable:!0}),e.prototype.getCompilationKey=function(e,t){var a=e.map(function(e){return e.name}).sort(),r=t.map(function(e){return e.name}).sort();return a.join(this.SEPERATOR)+"--"+r.join(this.SEPERATOR)},e.prototype.compile=function(e,t){var a=getExecutionSubgraph(e,t,this.weightMap),r=a.missingInputs,n=a.dynamicNode,s=a.syncInputs;if(null!=n)throw new Error("This execution contains the node '"+n.name+"', which has the dynamic op '"+n.op+"'. Please use model.executeAsync() instead. Alternatively, to avoid the dynamic ops, specify the inputs ["+s+"]");if(r.length>0){var o=t.map(function(e){return e.name}),p=Object.keys(e);throw new Error("Cannot compute the outputs ["+o+"] from the provided inputs ["+p+"]. Missing the following inputs: ["+r+"]")}return getNodesInTopologicalOrder(this.graph,this.weightMap,a)},e.prototype.execute=function(e,t){var a=this,r=Object.keys(e).sort();this.checkInputs(e),this.checkInputShapeAndType(e),this.checkOutputs(t);var n=r.map(function(e){return a.graph.nodes[e]}),s=t.map(function(e){return a.graph.nodes[parseNodeName(e)[0]]}),o=this.getCompilationKey(n,s),p=this.compiledMap.get(o);null==p&&(p=this.compile(e,s),this.compiledMap.set(o,p));var u={};return Object(_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["tidy"])(function(){var r=new ExecutionContext(a._weightMap,u),n=__assign({},a.weightMap);Object.keys(e).forEach(function(t){n[t]=[e[t]]});for(var s=a.getFrozenTensorIds(n),o={},i=0;i0?(g=this.processStack(n,l,t,c,f,y,a,d,p),[4,Promise.all(g)]):[3,3];case 2:return V.sent(),[3,1];case 3:if(null==i&&console.warn("This model execution did not contain any nodes with control flow or dynamic output shapes. You can use model.execute() instead."),(h=s.filter(function(e){return!isControlFlow(e)&&!getTensor(e.name,c,t)}).map(function(e){return e.name})).length>0)throw N="",null!=i&&(N="Alternatively, to avoid the dynamic ops, use model.execute() and specify the inputs ["+m+"]"),new Error("Cannot compute the outputs ["+h+"] from the provided inputs ["+r+"]. Consider providing the following inputs: ["+u+"]. "+N);return[2,c]}})})},e.prototype.processStack=function(e,t,a,r,n,s,o,p,u){for(var i=this,m=[],l=function(){var l=t.pop();a.currentContext=l.contexts;var d="";if("Enter"===l.node.op&&getParamValue("isConstant",l.node,r,a)&&(d=getNodeNameAndIndex(l.node.name,a)[0]),-1===e.indexOf(l.node)){var y=executeOp$16(l.node,r,a);d||(d=getNodeNameAndIndex(l.node.name,a)[0]);var f=a.currentContext;y instanceof Promise?m.push(y.then(function(e){return r[d]=e,a.currentContext=f,i.checkTensorForDisposal(d,l.node,r,a,s,o,p),i.processChildNodes(l.node,t,a,r,n,u),e})):(r[d]=y,c.checkTensorForDisposal(d,l.node,r,a,s,o,p),c.processChildNodes(l.node,t,a,r,n,u))}else c.processChildNodes(l.node,t,a,r,n,u)},c=this;t.length>0;)l();return m},e.prototype.processChildNodes=function(e,t,a,r,n,s){e.children.forEach(function(e){var o=getNodeNameAndIndex(e.name,a)[0];!n[o]&&s.has(e.name)&&("Merge"===e.op?e.inputNames.some(function(e){return!!getTensor(e,r,a)})&&(n[o]=!0,t.push({contexts:a.currentContext,node:e})):e.inputNames.every(function(e){return!!getTensor(e,r,a)})&&(n[o]=!0,t.push({contexts:a.currentContext,node:e})))})},e.prototype.dispose=function(){var e=this;Object.keys(this.weightMap).forEach(function(t){return e.weightMap[t].forEach(function(e){return e.dispose()})})},e.prototype.checkInputShapeAndType=function(e){var t=this;Object.keys(e).forEach(function(a){var r=e[a],n=t.graph.nodes[a];if(n.attrParams.shape&&n.attrParams.shape.value){var s=n.attrParams.shape.value,o=s.length===r.shape.length&&r.shape.every(function(e,t){return-1===s[t]||s[t]===e});_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["util"].assert(o,function(){return"The shape of dict['"+n.name+"'] provided in model.execute(dict) must be ["+s+"], but was ["+r.shape+"]"})}n.attrParams.dtype&&n.attrParams.dtype.value&&_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["util"].assert(r.dtype===n.attrParams.dtype.value,function(){return"The dtype of dict['"+n.name+"'] provided in model.execute(dict) must be "+n.attrParams.dtype.value+", but was "+r.dtype})})},e.prototype.checkInputs=function(e){var t=this,a=Object.keys(e).filter(function(e){return!t.graph.nodes[e]});if(a.length>0)throw new Error("The dict provided in model.execute(dict) has keys: ["+a+"] that are not part of graph")},e.prototype.checkOutputs=function(e){var t=this;e.forEach(function(e){var a=parseNodeName(e)[0];if(!t.graph.nodes[a])throw new Error("The output '"+e+"' is not found in the graph")})},e}(),TFHUB_SEARCH_PARAM="?tfjs-format=file",DEFAULT_MODEL_NAME="model.json",GraphModel=function(){function e(e,t){void 0===t&&(t={}),this.modelUrl=e,this.loadOptions=t,this.version="n/a",null==t&&(this.loadOptions={})}return Object.defineProperty(e.prototype,"modelVersion",{get:function(){return this.version},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"inputNodes",{get:function(){return this.executor.inputNodes},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputNodes",{get:function(){return this.executor.outputNodes},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"inputs",{get:function(){return this.executor.inputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"outputs",{get:function(){return this.executor.outputs},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"weights",{get:function(){return this.executor.weightMap},enumerable:!0,configurable:!0}),e.prototype.findIOHandler=function(){var e=this.modelUrl;if(null!=e.load)this.handler=e;else if(null!=this.loadOptions.requestInit)this.handler=_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["io"].browserHTTPRequest(e,this.loadOptions);else{var t=_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["io"].getLoadHandlers(e,this.loadOptions.onProgress);if(0===t.length)t.push(_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["io"].browserHTTPRequest(e,this.loadOptions));else if(t.length>1)throw new Error("Found more than one ("+t.length+") load handlers for URL '"+[e]+"'");this.handler=t[0]}},e.prototype.load=function(){return __awaiter(this,void 0,void 0,function(){var e,t,a;return __generator(this,function(r){switch(r.label){case 0:if(this.findIOHandler(),null==this.handler.load)throw new Error("Cannot proceed with model loading because the IOHandler provided does not have the `load` method implemented.");return[4,this.handler.load()];case 1:return e=r.sent(),t=e.modelTopology,this.version=t.versions.producer+"."+t.versions.minConsumer,a=_tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["io"].decodeWeights(e.weightData,e.weightSpecs),this.executor=new GraphExecutor(OperationMapper.Instance.transformGraph(t)),this.executor.weightMap=this.convertTensorMapToTensorsMap(a),[2,!0]}})})},e.prototype.predict=function(e,t){return this.execute(e,this.outputNodes)},e.prototype.normalizeInputs=function(e){if(!(e instanceof _tensorflow_tfjs_core__WEBPACK_IMPORTED_MODULE_0__["Tensor"]||Array.isArray(e)))return e;if((e=Array.isArray(e)?e:[e]).length!==this.inputNodes.length)throw new Error("Input tensor count mismatch,the graph model has "+this.inputNodes.length+" placeholders, while there are "+e.length+" input tensors.");return this.inputNodes.reduce(function(t,a,r){return t[a]=e[r],t},{})},e.prototype.normalizeOutputs=function(e){return e=e||this.outputNodes,Array.isArray(e)?e:[e]},e.prototype.execute=function(e,t){e=this.normalizeInputs(e),t=this.normalizeOutputs(t);var a=this.executor.execute(e,t);return a.length>1?a:a[0]},e.prototype.executeAsync=function(e,t){return __awaiter(this,void 0,void 0,function(){var a;return __generator(this,function(r){switch(r.label){case 0:return e=this.normalizeInputs(e),t=this.normalizeOutputs(t),[4,this.executor.executeAsync(e,t)];case 1:return[2,(a=r.sent()).length>1?a:a[0]]}})})},e.prototype.convertTensorMapToTensorsMap=function(e){return Object.keys(e).reduce(function(t,a){return t[a]=[e[a]],t},{})},e.prototype.dispose=function(){this.executor.dispose()},e}();function loadGraphModel(e,t){return void 0===t&&(t={}),__awaiter(this,void 0,void 0,function(){var a;return __generator(this,function(r){switch(r.label){case 0:if(null==e)throw new Error("modelUrl in loadGraphModel() cannot be null. Please provide a url or an IOHandler that loads the model");return null==t&&(t={}),t.fromTFHub&&null==e.load&&(e.endsWith("/")||(e+="/"),e=""+e+DEFAULT_MODEL_NAME+TFHUB_SEARCH_PARAM),[4,(a=new GraphModel(e,t)).load()];case 1:return r.sent(),[2,a]}})})}var version="1.2.11"; +//# sourceMappingURL=tf-converter.esm.js.map + +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../buffer/index.js */ "./node_modules/buffer/index.js").Buffer)) + +/***/ }), + +/***/ "./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js": +/*!****************************************************************!*\ + !*** ./node_modules/@tensorflow/tfjs-core/dist/tf-core.esm.js ***! + \****************************************************************/ +/*! exports provided: AdadeltaOptimizer, AdagradOptimizer, AdamOptimizer, AdamaxOptimizer, DataStorage, ENV, Environment, KernelBackend, MomentumOptimizer, Optimizer, RMSPropOptimizer, Rank, Reduction, SGDOptimizer, Tensor, TensorBuffer, Variable, abs, acos, acosh, add, addN, addStrict, all, any, argMax, argMin, asin, asinh, atan, atan2, atanh, avgPool, avgPool3d, backend, backend_util, basicLSTMCell, batchNorm, batchNorm2d, batchNorm3d, batchNorm4d, batchNormalization, batchNormalization2d, batchNormalization3d, batchNormalization4d, batchToSpaceND, booleanMaskAsync, browser, buffer, cast, ceil, clipByValue, clone, complex, concat, concat1d, concat2d, concat3d, concat4d, conv1d, conv2d, conv2dTranspose, conv3d, conv3dTranspose, cos, cosh, cumsum, customGrad, deprecationWarn, depthToSpace, depthwiseConv2d, diag, disableDeprecationWarnings, dispose, disposeVariables, div, divStrict, dot, dropout, elu, enableDebugMode, enableProdMode, engine, env, equal, equalStrict, erf, exp, expandDims, expm1, eye, fft, fill, findBackend, findBackendFactory, floor, floorDiv, frame, fused, gather, gatherND, getBackend, grad, grads, greater, greaterEqual, greaterEqualStrict, greaterStrict, hammingWindow, hannWindow, ifft, imag, image, inTopKAsync, io, irfft, isFinite, isInf, isNaN, keep, leakyRelu, less, lessEqual, lessEqualStrict, lessStrict, linalg, linspace, localResponseNormalization, log, log1p, logSigmoid, logSoftmax, logSumExp, logicalAnd, logicalNot, logicalOr, logicalXor, losses, matMul, math, max, maxPool, maxPool3d, maximum, maximumStrict, mean, memory, min, minimum, minimumStrict, mod, modStrict, moments, movingAverage, mul, mulStrict, multiRNNCell, multinomial, neg, nextFrame, norm, notEqual, notEqualStrict, oneHot, ones, onesLike, op, outerProduct, pad, pad1d, pad2d, pad3d, pad4d, pool, pow, powStrict, prelu, print, prod, profile, rand, randomGamma, randomNormal, randomUniform, range, ready, real, reciprocal, registerBackend, relu, relu6, removeBackend, reshape, reverse, reverse1d, reverse2d, reverse3d, reverse4d, rfft, round, rsqrt, scalar, scatterND, selu, separableConv2d, serialization, setBackend, setPlatform, setdiff1dAsync, sigmoid, sign, signal, sin, sinh, slice, slice1d, slice2d, slice3d, slice4d, softmax, softplus, spaceToBatchND, sparseToDense, spectral, split, sqrt, square, squaredDifference, squaredDifferenceStrict, squeeze, stack, step, stft, stridedSlice, sub, subStrict, sum, tan, tanh, tensor, tensor1d, tensor2d, tensor3d, tensor4d, tensor5d, tensor6d, tensor_util, test_util, tidy, tile, time, topk, train, transpose, truncatedNormal, unsortedSegmentSum, unstack, util, valueAndGrad, valueAndGrads, variable, variableGrads, version_core, webgl, where, whereAsync, zeros, zerosLike */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* WEBPACK VAR INJECTION */(function(global, process, Buffer, setImmediate) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdadeltaOptimizer", function() { return Ap; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdagradOptimizer", function() { return Tp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdamOptimizer", function() { return Dp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdamaxOptimizer", function() { return _p; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DataStorage", function() { return Zr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ENV", function() { return i; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Environment", function() { return o; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KernelBackend", function() { return to; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MomentumOptimizer", function() { return Fp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Optimizer", function() { return Sp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RMSPropOptimizer", function() { return Mp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Rank", function() { return ct; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Reduction", function() { return Pc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SGDOptimizer", function() { return Op; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tensor", function() { return ut; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TensorBuffer", function() { return ot; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Variable", function() { return lt; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "abs", function() { return Ts; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "acos", function() { return Ds; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "acosh", function() { return _s; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "add", function() { return Du; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addN", function() { return _u; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "addStrict", function() { return Ou; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "all", function() { return Yl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "any", function() { return Ql; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "argMax", function() { return Jl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "argMin", function() { return Zl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asin", function() { return Os; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "asinh", function() { return Fs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "atan", function() { return Ms; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "atan2", function() { return Fu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "atanh", function() { return Bs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "avgPool", function() { return Ul; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "avgPool3d", function() { return Gl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backend", function() { return Je; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "backend_util", function() { return bo; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "basicLSTMCell", function() { return mc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNorm", function() { return wu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNorm2d", function() { return Cu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNorm3d", function() { return Eu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNorm4d", function() { return Ru; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNormalization", function() { return bu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNormalization2d", function() { return gu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNormalization3d", function() { return yu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchNormalization4d", function() { return xu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "batchToSpaceND", function() { return nr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "booleanMaskAsync", function() { return dl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "browser", function() { return vp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return tr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cast", function() { return rr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ceil", function() { return Ps; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clipByValue", function() { return Ls; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clone", function() { return or; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "complex", function() { return gn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return Bn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat1d", function() { return Pn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat2d", function() { return Ln; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat3d", function() { return Wn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat4d", function() { return Un; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "conv1d", function() { return yl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "conv2d", function() { return xl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "conv2dTranspose", function() { return Nl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "conv3d", function() { return bl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "conv3dTranspose", function() { return Sl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cos", function() { return Ws; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cosh", function() { return Us; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cumsum", function() { return ar; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "customGrad", function() { return Xr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "deprecationWarn", function() { return Be; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthToSpace", function() { return ir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "depthwiseConv2d", function() { return El; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "diag", function() { return Ac; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "disableDeprecationWarnings", function() { return Me; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dispose", function() { return ze; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "disposeVariables", function() { return Pe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "div", function() { return Mu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "divStrict", function() { return Bu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dot", function() { return Tl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dropout", function() { return Tc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elu", function() { return sc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableDebugMode", function() { return Fe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "enableProdMode", function() { return Oe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "engine", function() { return Le; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "env", function() { return a; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "equal", function() { return Ju; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "equalStrict", function() { return Zu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "erf", function() { return Vs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "exp", function() { return zs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expandDims", function() { return sr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expm1", function() { return Gs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "eye", function() { return ur; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fft", function() { return Cc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fill", function() { return Dn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findBackend", function() { return Xe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findBackendFactory", function() { return Ye; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "floor", function() { return Hs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "floorDiv", function() { return Pu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "frame", function() { return Fc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fused", function() { return lh; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gather", function() { return pl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gatherND", function() { return Sc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBackend", function() { return Ke; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "grad", function() { return Hr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "grads", function() { return qr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "greater", function() { return tl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "greaterEqual", function() { return el; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "greaterEqualStrict", function() { return nl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "greaterStrict", function() { return rl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hammingWindow", function() { return Oc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "hannWindow", function() { return _c; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ifft", function() { return Ec; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "imag", function() { return xn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "image", function() { return ah; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "inTopKAsync", function() { return Lc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "io", function() { return hp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "irfft", function() { return Ic; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isFinite", function() { return nu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isInf", function() { return eu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isNaN", function() { return tu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "keep", function() { return Ge; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "leakyRelu", function() { return uc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "less", function() { return ol; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lessEqual", function() { return al; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lessEqualStrict", function() { return il; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "lessStrict", function() { return sl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linalg", function() { return Jc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "linspace", function() { return _n; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "localResponseNormalization", function() { return dc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log", function() { return qs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "log1p", function() { return $s; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logSigmoid", function() { return Ks; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logSoftmax", function() { return Jr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logSumExp", function() { return tc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logicalAnd", function() { return Iu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logicalNot", function() { return ku; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logicalOr", function() { return Nu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "logicalXor", function() { return Su; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "losses", function() { return jc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "matMul", function() { return Al; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "math", function() { return fp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return ec; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maxPool", function() { return Wl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maxPool3d", function() { return zl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maximum", function() { return Lu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maximumStrict", function() { return Wu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mean", function() { return nc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "memory", function() { return We; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return rc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "minimum", function() { return Uu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "minimumStrict", function() { return Vu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mod", function() { return zu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "modStrict", function() { return Gu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "moments", function() { return oc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "movingAverage", function() { return yc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mul", function() { return Hu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mulStrict", function() { return qu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multiRNNCell", function() { return gc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multinomial", function() { return lr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "neg", function() { return js; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "nextFrame", function() { return Wp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "norm", function() { return vc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "notEqual", function() { return ul; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "notEqualStrict", function() { return ll; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "oneHot", function() { return cr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ones", function() { return An; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onesLike", function() { return Fn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "op", function() { return mn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "outerProduct", function() { return Dl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pad", function() { return hr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pad1d", function() { return pr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pad2d", function() { return fr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pad3d", function() { return dr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pad4d", function() { return vr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pool", function() { return Vl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pow", function() { return $u; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "powStrict", function() { return Ku; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prelu", function() { return lc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "print", function() { return er; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "prod", function() { return ic; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "profile", function() { return Ue; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rand", function() { return mr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randomGamma", function() { return yr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randomNormal", function() { return gr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "randomUniform", function() { return xr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "range", function() { return On; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ready", function() { return $e; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "real", function() { return yn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reciprocal", function() { return Xs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "registerBackend", function() { return Qe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "relu", function() { return cc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "relu6", function() { return hc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeBackend", function() { return je; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reshape", function() { return br; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverse", function() { return _l; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverse1d", function() { return Ol; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverse2d", function() { return Fl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverse3d", function() { return Ml; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverse4d", function() { return Bl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rfft", function() { return Rc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "round", function() { return Ys; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rsqrt", function() { return Qs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scalar", function() { return Cn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scatterND", function() { return wc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "selu", function() { return pc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "separableConv2d", function() { return kl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "serialization", function() { return xp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setBackend", function() { return qe; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setPlatform", function() { return Ze; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "setdiff1dAsync", function() { return Nr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sigmoid", function() { return Js; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sign", function() { return Zs; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "signal", function() { return Bc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sin", function() { return ru; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sinh", function() { return ou; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "slice", function() { return Hl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "slice1d", function() { return ql; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "slice2d", function() { return $l; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "slice3d", function() { return Kl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "slice4d", function() { return jl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "softmax", function() { return Qr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "softplus", function() { return au; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spaceToBatchND", function() { return wr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sparseToDense", function() { return Nc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "spectral", function() { return kc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "split", function() { return Vn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sqrt", function() { return iu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "square", function() { return su; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "squaredDifference", function() { return ju; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "squaredDifferenceStrict", function() { return Xu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "squeeze", function() { return Cr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stack", function() { return Er; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "step", function() { return uu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stft", function() { return Mc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stridedSlice", function() { return xc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sub", function() { return Yu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subStrict", function() { return Qu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sum", function() { return ac; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tan", function() { return lu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tanh", function() { return cu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor", function() { return bn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor1d", function() { return En; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor2d", function() { return Rn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor3d", function() { return In; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor4d", function() { return kn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor5d", function() { return Nn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor6d", function() { return Sn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tensor_util", function() { return Et; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "test_util", function() { return Ip; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tidy", function() { return Ve; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tile", function() { return Rr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "time", function() { return He; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "topk", function() { return bc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "train", function() { return Pp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transpose", function() { return fc; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "truncatedNormal", function() { return Ir; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unsortedSegmentSum", function() { return fl; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unstack", function() { return kr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "util", function() { return j; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "valueAndGrad", function() { return $r; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "valueAndGrads", function() { return Kr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "variable", function() { return vt; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "variableGrads", function() { return jr; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "version_core", function() { return kp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "webgl", function() { return Np; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "where", function() { return Au; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "whereAsync", function() { return Tu; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zeros", function() { return Tn; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zerosLike", function() { return Mn; }); +/** + * @license + * Copyright 2019 Google LLC. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================================= + */ +var t=function(e,n){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])})(e,n)};function e(e,n){function r(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}function n(t,e,n,r){return new(n||(n=Promise))(function(o,a){function i(t){try{u(r.next(t))}catch(t){a(t)}}function s(t){try{u(r.throw(t))}catch(t){a(t)}}function u(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(i,s)}u((r=r.apply(t,e||[])).next())})}function r(t,e){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(a){return function(s){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;i;)try{if(n=1,r&&(o=2&a[0]?r.return:a[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,a[1])).done)return o;switch(r=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return i.label++,{value:a[1],done:!1};case 5:i.label++,r=a[1],a=[0];continue;case 7:a=i.ops.pop(),i.trys.pop();continue;default:if(!(o=(o=i.trys).length>0&&o[o.length-1])&&(6===a[0]||2===a[0])){i=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]0;)r=Math.random()*e|0,n=t[--e],t[e]=t[r],t[r]=n}function u(t,e,n){return Math.max(t,Math.min(e,n))}function l(t){return t%2==0?t:t+1}function c(t){for(var e=0,n=0;n=n?o():setTimeout(i,s)}};i()})}function C(t,e){for(var n=1,r=-1,o=0;o=0)n*=t[o];else if(-1===t[o]){if(-1!==r)throw Error("Shapes can only have 1 implicit size. Found -1 at dim "+r+" and dim "+o);r=o}else if(t[o]<0)throw Error("Shapes can not be < 0. Found "+t[o]+" at dim "+o);if(-1===r){if(e>0&&e!==n)throw Error("Size("+e+") must match the product of shape "+t);return t}if(0===n)throw Error("Cannot infer the missing size in ["+t+"] when there are 0 elements");if(e%n!=0)throw Error("The implicit shape can't be a fractional number. Got "+e+" / "+n);var a=t.slice();return a[r]=e/n,a}function E(t,e){var n=e.length;return h((t=null==t?e.map(function(t,e){return e}):[].concat(t)).every(function(t){return t>=-n&&ts)&&1===t[s]&&(n.push(t[s]),r.push(s)),a[i]<=s&&i++}1!==t[s]&&(n.push(t[s]),r.push(s))}return{newShape:n,keptDims:r}}function I(t,e){var n=null;if(null==t||"float32"===t)n=new Float32Array(e);else if("int32"===t)n=new Int32Array(e);else{if("bool"!==t)throw new Error("Unknown data type "+t);n=new Uint8Array(e)}return n}function k(t,e){var n=null;if(null==t||"float32"===t)n=new Float32Array(e);else if("int32"===t)n=new Int32Array(e);else if("bool"===t)n=new Uint8Array(e);else{if("string"!==t)throw new Error("Unknown data type "+t);n=new Array(e)}return n}function N(t,e){for(var n=0;n=0;--r)n[r]=n[r+1]*t[r+1];return n}function U(t,e,n){if("string"===e)throw new Error("Cannot convert a string[] to a TypedArray");if(Array.isArray(t)&&(t=d(t)),n&&N(t,e),function(t,e){return t instanceof Float32Array&&"float32"===e||t instanceof Int32Array&&"int32"===e||t instanceof Uint8Array&&"bool"===e}(t,e))return t;if(null==e||"float32"===e||"complex64"===e)return new Float32Array(t);if("int32"===e)return new Int32Array(t);if("bool"===e){for(var r=new Uint8Array(t.length),o=0;o=0,function(){return"Tensor must have a shape comprised of positive integers but got shape ["+t+"]."})})}function $(t,e){return void 0===e&&(e="utf-8"),e=e||"utf-8",a().platform.encode(t,e)}function K(t,e){return void 0===e&&(e="utf-8"),e=e||"utf-8",a().platform.decode(t,e)}var j=Object.freeze({shuffle:s,clamp:u,nearestLargerEven:l,sum:c,randUniform:function(t,e){var n=Math.random();return e*n+(1-n)*t},distSquared:function(t,e){for(var n=0,r=0;r0?f:"")+" "}console.log("%c"+s+"\t%c"+i+"\t%c"+u+"D "+c+"\t%c"+l+"\t%c"+h+"\t%c"+a,"font-weight:bold","color:red","color:blue","color: orange","color: green","color: steelblue")},t}(),Q=20,J=3,Z=7;function tt(t,e,n,r){var o=W(e),a=function(t,e,n,r){var o=v(e),a=r[r.length-1],i=new Array(a).fill(0),s=e.length,u="complex64"===n?rt(t):t;if(s>1)for(var l=0;lQ){var h=J*s,p=Array.from(e.slice(0,h)),f=Array.from(e.slice(u-J*s,u));return"complex64"===r&&(p=rt(p),f=rt(f)),["["+p.map(function(t,e){return et(t,a[e],r)}).join(", ")+", ..., "+f.map(function(t,e){return et(t,a[u-J+e],r)}).join(", ")+"]"]}var d="complex64"===r?rt(e):Array.from(e);return["["+d.map(function(t,e){return et(t,a[e],r)}).join(", ")+"]"]}var v=n.slice(1);var m=o.slice(1);var g=o[0]*s;var y=[];if(u>Q){for(var x=0;x=this.shape[n]){var i="Requested out of range element at "+t+". Buffer shape="+this.shape;throw new Error(i)}n++}for(var s=t[t.length-1],u=0;u0&&(t.unreliable=!0,null==t.reasons&&(t.reasons=[]),t.reasons.push("Memory usage by string tensors is approximate (2 bytes per character)")),t},t.prototype.profile=function(t){return n(this,void 0,void 0,function(){var e,n;return r(this,function(r){return this.state.profiling=!0,e=this.state.numBytes,n=this.state.numTensors,this.state.activeProfile.kernels=[],this.state.activeProfile.result=t(),this.state.profiling=!1,this.state.activeProfile.peakBytes=Math.max.apply(Math,this.state.activeProfile.kernels.map(function(t){return t.totalBytesSnapshot})),this.state.activeProfile.newBytes=this.state.numBytes-e,this.state.activeProfile.newTensors=this.state.numTensors-n,[2,this.state.activeProfile]})})},t.prototype.isTapeOn=function(){return this.state.gradientDepth>0&&0===this.state.kernelDepth},t.prototype.addTapeNode=function(t,e,n){var r={};t.forEach(function(t,e){r[e]=t});var o={id:this.state.nextTapeNodeId++,name:this.state.activeScope.name,inputs:r,outputs:[e],gradient:function(t){var e=n(t),r={};return e.forEach(function(t,e){r[e]=function(){return t}}),r}};this.state.activeTape.push(o)},t.prototype.keep=function(t){return t.kept=!0,t},t.prototype.startTape=function(){0===this.state.gradientDepth&&(this.state.activeTape=[]),this.state.gradientDepth++},t.prototype.endTape=function(){this.state.gradientDepth--},t.prototype.startScope=function(t){var e={track:[],name:"unnamed scope",id:this.state.nextScopeId++};t&&(e.name=t),this.state.scopeStack.push(e),this.state.activeScope=e},t.prototype.endScope=function(t){for(var e=this,n=wt(t),r=new Set(n.map(function(t){return t.id})),o=0;o0,function(){return"gradients() received an empty list of xs."}),null!=n&&"float32"!==n.dtype)throw new Error("dy must have 'float32' dtype, but has '"+n.dtype+"'");var a=this.scopedRun(function(){return o.startTape()},function(){return o.endTape()},function(){return o.tidy("forward",t)});h(a instanceof ut,function(){return"The result y returned by f() must be a tensor."});var i=function(t,e,n){for(var r={},o={},a=0;a=0;a--)for(i=(d=t[a]).inputs,c=0;c0)throw new Error("Cannot compute gradient of y=f(x) with respect to x. Make sure that the f you passed encloses all operations that lead from x to y.");return this.tidy("backward",function(){var t,r,s={};s[a.id]=null==n?(t=a.shape,r=z(v(t),"float32"),ut.make(t,{values:r})):n,function(t,e,n){for(var r=function(r){var o=e[r],a=[];if(o.outputs.forEach(function(e){var n=t[e.id];if(null!=n)a.push(n);else{var r=ut.make(e.shape,{values:G(e.size,e.dtype)},e.dtype);a.push(r)}}),null==o.gradient)throw new Error("Cannot compute gradient: gradient function not found for "+o.name+".");var i=o.gradient(1===o.outputs.length?a[0]:a),s=function(e){if(!(e in i))throw new Error("Cannot backprop through input "+e+". Available gradients found: "+Object.keys(i)+".");var r=n(function(){return i[e]()});if("float32"!==r.dtype)throw new Error("Error in gradient for op "+o.name+". The gradient of input "+e+" must have 'float32' dtype, but has '"+r.dtype+"'");var a=o.inputs[e];if(!m(r.shape,a.shape))throw new Error("Error in gradient for op "+o.name+". The gradient of input '"+e+"' has shape '"+r.shape+"', which does not match the shape of the input '"+a.shape+"'");if(null==t[a.id])t[a.id]=r;else{var s=t[a.id];t[a.id]=s.add(r),s.dispose()}};for(var u in o.inputs)s(u)},o=e.length-1;o>=0;o--)r(o)}(s,i,function(t){return o.tidy(t)});var u=e.map(function(t){return s[t.id]});return 0===o.state.gradientDepth&&(o.state.activeTape.forEach(function(t){for(var e in t.saved)t.saved[e].dispose()}),o.state.activeTape=null),{value:a,grads:u}})},t.prototype.customGrad=function(t){var e=this;return h(P(t),function(){return"The f passed in customGrad(f) must be a function."}),function(){for(var n,r=[],o=0;on||e>n){r="["+t+"x"+e+"]";throw new Error("Requested texture size "+r+" greater than WebGL maximum on this browser / GPU "+("["+n+"x"+n+"]")+".")}}function oe(t,e){return de(t,e,function(){return t.createFramebuffer()},"Unable to create WebGLFramebuffer.")}function ae(t,e,n,r,o,a,i,s){var u=t.getAttribLocation(n,r);return-1!==u&&(Ut(t,e,function(){return t.bindBuffer(t.ARRAY_BUFFER,o)}),Ut(t,e,function(){return t.vertexAttribPointer(u,a,t.FLOAT,!1,i,s)}),Ut(t,e,function(){return t.enableVertexAttribArray(u)}),!0)}function ie(t,e,n,r){ve(t,r),Ut(t,e,function(){return t.activeTexture(t.TEXTURE0+r)}),Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)})}function se(t,e,n,r){return de(t,e,function(){return t.getUniformLocation(n,r)},'uniform "'+r+'" not present in program.')}function ue(t,e,n){return t.getUniformLocation(e,n)}function le(t,e,n,r,o,a){Ut(t,e,function(){return ie(t,e,r,a)}),Ut(t,e,function(){return t.uniform1i(o,a)})}function ce(t,e,n,r){Ut(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,r)}),Ut(t,e,function(){return t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,n,0)})}function he(t,e,n){Ut(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,n)}),Ut(t,e,function(){return t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,null,0)})}function pe(t){var e=t.checkFramebufferStatus(t.FRAMEBUFFER);if(e!==t.FRAMEBUFFER_COMPLETE)throw new Error("Error binding framebuffer: "+fe(t,e))}function fe(t,e){switch(e){case t.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_ATTACHMENT";case t.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";case t.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:return"FRAMEBUFFER_INCOMPLETE_DIMENSIONS";case t.FRAMEBUFFER_UNSUPPORTED:return"FRAMEBUFFER_UNSUPPORTED";default:return"unknown error "+e}}function de(t,e,n,r){var o=Ut(t,e,function(){return n()});if(null==o)throw new Error(r);return o}function ve(t,e){var n=t.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1,r=e+t.TEXTURE0;if(rn)throw new Error("textureUnit must be in "+("[gl.TEXTURE0, gl.TEXTURE"+n+"]")+".")}function me(t,e){return void 0===e&&(e=2),v(t.slice(0,t.length-e))}function ge(t){if(0===t.length)throw Error("Cannot get rows and columns of an empty shape array.");return[t.length>1?t[t.length-2]:1,t[t.length-1]]}function ye(t){var e=[1,1,1];return 0===t.length||1===t.length&&1===t[0]||(e=[me(t)].concat(ge(t))),e}function xe(t,e){var n;void 0===e&&(e=!1);var r=a().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(e&&(r*=2,1===(t=t.map(function(e,n){return n>=t.length-2?l(t[n]):t[n]})).length&&(t=[2,t[0]])),2!==t.length){var o=R(t);t=o.newShape}var i=v(t);if(t.length<=1&&i<=r)return[1,i];if(2===t.length&&t[0]<=r&&t[1]<=r)return t;if(3===t.length&&t[0]*t[1]<=r&&t[2]<=r)return[t[0]*t[1],t[2]];if(3===t.length&&t[0]<=r&&t[1]*t[2]<=r)return[t[0],t[1]*t[2]];if(4===t.length&&t[0]*t[1]*t[2]<=r&&t[3]<=r)return[t[0]*t[1]*t[2],t[3]];if(4===t.length&&t[0]<=r&&t[1]*t[2]*t[3]<=r)return[t[0],t[1]*t[2]*t[3]];if(e){var s=me(t),u=2,c=2;return t.length&&(u=(n=ge(t))[0],c=n[1]),x(i=s*(u/2)*(c/2)).map(function(t){return 2*t})}return x(i)}function be(t){return t%2==0}function we(t,e){if(m(t=t.slice(-2),e=e.slice(-2)))return!0;if(!t.length||!e.length)return!0;if(0===t[0]||0===t[1]||0===e[0]||0===e[1])return!0;if(t.length!==e.length){var n=t.slice(-1)[0],r=e.slice(-1)[0];if(n===r)return!0;if(be(n)&&be(r)&&(1===t[0]||1===e[0]))return!0}return t[1]===e[1]&&be(t[0])&&be(e[0])}function Ce(t){if(null==jt){var e=Ft(t);jt=e.getParameter(e.MAX_TEXTURE_SIZE)}return jt}function Ee(t){if(null==Xt){var e=Ft(t);Xt=e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS)}return Math.min(16,Xt)}function Re(t){if(0===t)return 0;var e=Ft(t);return Ie(e,"EXT_disjoint_timer_query_webgl2")&&2===t?2:Ie(e,"EXT_disjoint_timer_query")?1:0}function Ie(t,e){return null!=t.getExtension(e)}function ke(t){try{if(null!=Ft(t))return!0}catch(t){return!1}return!1}function Ne(t){if(0===t)return!1;var e=Ft(t);if(1===t){if(!Ie(e,"OES_texture_float"))return!1}else if(!Ie(e,"EXT_color_buffer_float"))return!1;return Ae(e)}function Se(t){if(0===t)return!1;var e=Ft(t);if(1!==t){if(Ie(e,"EXT_color_buffer_float"))return Ae(e);if(Ie(e,"EXT_color_buffer_half_float")){var n=e.getExtension("EXT_color_buffer_half_float");return function(t,e){var n=Wt(t,e),r=t.createTexture();t.bindTexture(t.TEXTURE_2D,r);t.texImage2D(t.TEXTURE_2D,0,n.internalFormatHalfFloat,1,1,0,n.textureFormatFloat,n.textureTypeHalfFloat,null);var o=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,o),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,r,0);var a=t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE;return t.bindTexture(t.TEXTURE_2D,null),t.bindFramebuffer(t.FRAMEBUFFER,null),t.deleteTexture(r),t.deleteFramebuffer(o),a}(e,n)}return!1}return!!Ie(e,"OES_texture_float")&&(!!Ie(e,"WEBGL_color_buffer_float")&&Ae(e))}function Ae(t){var e=Wt(t),n=t.createTexture();t.bindTexture(t.TEXTURE_2D,n);t.texImage2D(t.TEXTURE_2D,0,e.internalFormatFloat,1,1,0,e.textureFormatFloat,e.textureTypeFloat,null);var r=t.createFramebuffer();t.bindFramebuffer(t.FRAMEBUFFER,r),t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,n,0);var o=t.checkFramebufferStatus(t.FRAMEBUFFER)===t.FRAMEBUFFER_COMPLETE;return t.bindTexture(t.TEXTURE_2D,null),t.bindFramebuffer(t.FRAMEBUFFER,null),t.deleteTexture(n),t.deleteFramebuffer(r),o}function Te(t){return 2===t&&null!=Ft(t).fenceSync}var De=Object.freeze({callAndCheck:Ut,canBeRepresented:Gt,getWebGLErrorMessage:Ht,getExtensionOrThrow:qt,createVertexShader:$t,createFragmentShader:Kt,createProgram:Qt,linkProgram:Jt,validateProgram:Zt,createStaticVertexBuffer:te,createStaticIndexBuffer:ee,getNumChannels:function(){return 2===a().getNumber("WEBGL_VERSION")?1:4},createTexture:ne,validateTextureSize:re,createFramebuffer:oe,bindVertexBufferToProgramAttribute:ae,bindTextureUnit:ie,unbindTextureUnit:function(t,e,n){ve(t,n),Ut(t,e,function(){return t.activeTexture(t.TEXTURE0+n)}),Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)})},getProgramUniformLocationOrThrow:se,getProgramUniformLocation:ue,bindTextureToProgramUniformSampler:le,bindCanvasToFramebuffer:function(t,e){Ut(t,e,function(){return t.bindFramebuffer(t.FRAMEBUFFER,null)}),Ut(t,e,function(){return t.viewport(0,0,t.canvas.width,t.canvas.height)}),Ut(t,e,function(){return t.scissor(0,0,t.canvas.width,t.canvas.height)})},bindColorTextureToFramebuffer:ce,unbindColorTextureFromFramebuffer:he,validateFramebuffer:pe,getFramebufferErrorMessage:fe,getBatchDim:me,getRowsCols:ge,getShapeAs3D:ye,getTextureShapeFromLogicalShape:xe,isReshapeFree:we,getWebGLMaxTextureSize:Ce,resetMaxTextureSize:function(){jt=null},resetMaxTexturesInShader:function(){Xt=null},getMaxTexturesInShader:Ee,getWebGLDisjointQueryTimerVersion:Re,hasExtension:Ie,isWebGLVersionEnabled:ke,isCapableOfRenderingToFloatTexture:Ne,isDownloadFloatTextureEnabled:Se,isWebGLFenceEnabled:Te}),_e=a();function Oe(){a().set("PROD",!0)}function Fe(){a().set("DEBUG",!0)}function Me(){a().set("DEPRECATION_WARNINGS_ENABLED",!1),console.warn("TensorFlow.js deprecation warnings have been disabled.")}function Be(t){a().getBool("DEPRECATION_WARNINGS_ENABLED")&&console.warn(t+" You can disable deprecation warnings with tf.disableDeprecationWarnings().")}function Pe(){kt.disposeVariables()}function Le(){return kt}function We(){return kt.memory()}function Ue(t){return kt.profile(t)}function Ve(t,e){return kt.tidy(t,e)}function ze(t){wt(t).forEach(function(t){return t.dispose()})}function Ge(t){return kt.keep(t)}function He(t){return kt.time(t)}function qe(t){return kt.setBackend(t)}function $e(){return kt.ready()}function Ke(){return kt.backendName}function je(t){kt.removeBackend(t)}function Xe(t){return kt.findBackend(t)}function Ye(t){return kt.findBackendFactory(t)}function Qe(t,e,n){return void 0===n&&(n=1),kt.registerBackend(t,e,n)}function Je(){return kt.backend}function Ze(t,e){a().setPlatform(t,e)}function tn(){for(var t=[],e=0;e0,function(){return"Element arr["+r.join("][")+"] should be a primitive, but is an array of "+e.length+" elements"});h(e.length===n[0],function(){return"Element arr["+r.join("][")+"] should have "+n[0]+" elements, but has "+e.length+" elements"});var o=n.slice(1);for(var a=0;a=0&&(o=r),nn(r,o,e,n),null==t||!T(t)&&!Array.isArray(t)&&"number"!=typeof t&&"boolean"!=typeof t&&"string"!=typeof t){var i=null==t?"null":t.constructor.name;throw new Error("Argument '"+e+"' passed to '"+n+"' must be a Tensor or TensorLike, but got '"+i+"'")}var s=en(t,o);T(t)||Array.isArray(t)||(t=[t]);var u="string"!==o?U(t,o,a().getBool("DEBUG")):d(t,[],!0);return ut.make(s,{values:u},o)}function on(t,e,n,r){if(void 0===r&&(r="numeric"),!Array.isArray(t))throw new Error("Argument "+e+" passed to "+n+" must be a `Tensor[]` or `TensorLike[]`");return t.map(function(t,r){return rn(t,e+"["+r+"]",n)},r)}function an(t,e){for(var n=0;n=0&&e0}),_e.registerFlag("WEBGL_VERSION",function(){return ke(2)?2:ke(1)?1:0}),_e.registerFlag("WEBGL_BUFFER_SUPPORTED",function(){return 2===_e.get("WEBGL_VERSION")}),_e.registerFlag("WEBGL_CPU_FORWARD",function(){return!0}),_e.registerFlag("WEBGL_FORCE_F16_TEXTURES",function(){return!1}),_e.registerFlag("WEBGL_PACK",function(){return _e.getBool("HAS_WEBGL")}),_e.registerFlag("WEBGL_PACK_NORMALIZATION",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_CLIP",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_DEPTHWISECONV",function(){return!1}),_e.registerFlag("WEBGL_PACK_BINARY_OPERATIONS",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_UNARY_OPERATIONS",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_ARRAY_OPERATIONS",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_IMAGE_OPERATIONS",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_PACK_REDUCE",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_LAZILY_UNPACK",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_CONV_IM2COL",function(){return _e.getBool("WEBGL_PACK")}),_e.registerFlag("WEBGL_MAX_TEXTURE_SIZE",function(){return Ce(_e.getNumber("WEBGL_VERSION"))}),_e.registerFlag("WEBGL_MAX_TEXTURES_IN_SHADER",function(){return Ee(_e.getNumber("WEBGL_VERSION"))}),_e.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION",function(){var t=_e.getNumber("WEBGL_VERSION");return 0===t?0:Re(t)}),_e.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE",function(){return _e.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0&&(t=navigator.userAgent||navigator.vendor||window.opera,!(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4))));var t}),_e.registerFlag("WEBGL_RENDER_FLOAT32_CAPABLE",function(){return Ne(_e.getNumber("WEBGL_VERSION"))}),_e.registerFlag("WEBGL_RENDER_FLOAT32_ENABLED",function(){return!_e.getBool("WEBGL_FORCE_F16_TEXTURES")&&_e.getBool("WEBGL_RENDER_FLOAT32_CAPABLE")}),_e.registerFlag("WEBGL_DOWNLOAD_FLOAT_ENABLED",function(){return Se(_e.getNumber("WEBGL_VERSION"))}),_e.registerFlag("WEBGL_FENCE_API_ENABLED",function(){return Te(_e.getNumber("WEBGL_VERSION"))}),_e.registerFlag("WEBGL_SIZE_UPLOAD_UNIFORM",function(){return _e.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?4:0}),st=Be;var gn=mn({complex_:function(t,e){var n=rn(t,"real","complex"),r=rn(e,"imag","complex");return p(n.shape,r.shape,"real and imag shapes, "+n.shape+" and "+r.shape+", must match in call to tf.complex()."),kt.runKernel(function(t){return t.complex(n,r)},{$real:n,$imag:r})}}),yn=mn({real_:function(t){var e=rn(t,"input","real");return kt.runKernel(function(t){return t.real(e)},{$input:e})}}),xn=mn({imag_:function(t){var e=rn(t,"input","imag");return kt.runKernel(function(t){return t.imag(e)},{$input:e})}});function bn(t,e,n){return wn(t,e,en(t,n),n)}function wn(t,e,n,r){if(null==r&&(r=B(t)),"complex64"===r)throw new Error("Cannot construct a complex64 tensor directly. Please use tf.complex(real, imag).");if(!T(t)&&!Array.isArray(t)&&"number"!=typeof t&&"boolean"!=typeof t&&"string"!=typeof t)throw new Error("values passed to tensor(values) must be a number/boolean/string or an array of numbers/booleans/strings, or a TypedArray");if(null!=e){q(e);var o=v(e),i=v(n);h(o===i,function(){return"Based on the provided shape, ["+e+"], the tensor should have "+o+" values but has "+i});for(var s=0;s1)return Tn([0],r);var o=G(Math.abs(Math.ceil((e-t)/n)),r);e=1,function(){return"Pass at least one tensor to concat"});var n=on(t,"tensors","concat");"complex64"===n[0].dtype&&n.forEach(function(t){if("complex64"!==t.dtype)throw new Error("Cannot concatenate complex64 tensors with a tensor\n with dtype "+t.dtype+". ")}),e=E(e,n[0].shape)[0];var r=vn(n.map(function(t){return t.shape}),e);if(0===v(r))return bn([],r);if(1===(n=n.filter(function(t){return t.size>0})).length)return n[0];var o=n.map(function(t){return t.shape});dn(o,e);var a=n;return kt.runKernel(function(t){return t.concat(n,e)},a,function(t){var n=o.map(function(t){return t[e]});return Vn(t,n,e).map(function(t){return function(){return t}})})}}),Pn=mn({concat1d_:function(t){return Bn(t,0)}}),Ln=mn({concat2d_:function(t,e){return Bn(t,e)}}),Wn=mn({concat3d_:function(t,e){return Bn(t,e)}}),Un=mn({concat4d_:function(t,e){return Bn(t,e)}}),Vn=mn({split_:function(t,e,n){void 0===n&&(n=0);var r,o=rn(t,"x","split");return n=E(n,o.shape)[0],"number"==typeof e?(h(o.shape[n]%e==0,function(){return"Number of splits must evenly divide the axis."}),r=new Array(e).fill(o.shape[n]/e)):(h(o.shape[n]===e.reduce(function(t,e){return t+e}),function(){return"The sum of sizes must match the size of the axis dimension."}),r=e),kt.runKernel(function(t){return t.split(o,r,n)},{$x:o},function(t){return{$x:function(){return Bn(t,n)}}})}});"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function zn(t,e){return t(e={exports:{}},e.exports),e.exports}var Gn=zn(function(t){!function(t,e,n){function r(t){var e,n=this,r=(e=4022871197,function(t){t=t.toString();for(var n=0;n>>0,e=(r*=e)>>>0,e+=4294967296*(r-=e)}return 2.3283064365386963e-10*(e>>>0)});n.next=function(){var t=2091639*n.s0+2.3283064365386963e-10*n.c;return n.s0=n.s1,n.s1=n.s2,n.s2=t-(n.c=0|t)},n.c=1,n.s0=r(" "),n.s1=r(" "),n.s2=r(" "),n.s0-=r(t),n.s0<0&&(n.s0+=1),n.s1-=r(t),n.s1<0&&(n.s1+=1),n.s2-=r(t),n.s2<0&&(n.s2+=1),r=null}function o(t,e){return e.c=t.c,e.s0=t.s0,e.s1=t.s1,e.s2=t.s2,e}function a(t,e){var n=new r(t),a=e&&e.state,i=n.next;return i.int32=function(){return 4294967296*n.next()|0},i.double=function(){return i()+1.1102230246251565e-16*(2097152*i()|0)},i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.alea=a}(0,t,!1)}),Hn=zn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.x=0,e.y=0,e.z=0,e.w=0,e.next=function(){var t=e.x^e.x<<11;return e.x=e.y,e.y=e.z,e.z=e.w,e.w^=e.w>>>19^t^t>>>8},t===(0|t)?e.x=t:n+=t;for(var r=0;r>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xor128=a}(0,t,!1)}),qn=zn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.next=function(){var t=e.x^e.x>>>2;return e.x=e.y,e.y=e.z,e.z=e.w,e.w=e.v,(e.d=e.d+362437|0)+(e.v=e.v^e.v<<4^t^t<<1)|0},e.x=0,e.y=0,e.z=0,e.w=0,e.v=0,t===(0|t)?e.x=t:n+=t;for(var r=0;r>>4),e.next()}function o(t,e){return e.x=t.x,e.y=t.y,e.z=t.z,e.w=t.w,e.v=t.v,e.d=t.d,e}function a(t,e){var n=new r(t),a=e&&e.state,i=function(){return(n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xorwow=a}(0,t,!1)}),$n=zn(function(t){!function(t,e,n){function r(t){var e=this;e.next=function(){var t,n,r=e.x,o=e.i;return t=r[o],n=(t^=t>>>7)^t<<24,n^=(t=r[o+1&7])^t>>>10,n^=(t=r[o+3&7])^t>>>3,n^=(t=r[o+4&7])^t<<7,t=r[o+7&7],n^=(t^=t<<13)^t<<9,r[o]=n,e.i=o+1&7,n},function(t,e){var n,r=[];if(e===(0|e))r[0]=e;else for(e=""+e,n=0;n0;--n)t.next()}(e,t)}function o(t,e){return e.x=t.x.slice(),e.i=t.i,e}function a(t,e){null==t&&(t=+new Date);var n=new r(t),a=e&&e.state,i=function(){return(n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},i.int32=n.next,i.quick=i,a&&(a.x&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xorshift7=a}(0,t,!1)}),Kn=zn(function(t){!function(t,e,n){function r(t){var e=this;e.next=function(){var t,n,r=e.w,o=e.X,a=e.i;return e.w=r=r+1640531527|0,n=o[a+34&127],t=o[a=a+1&127],n^=n<<13,t^=t<<17,n^=n>>>15,t^=t>>>12,n=o[a]=n^t,e.i=a,n+(r^r>>>16)|0},function(t,e){var n,r,o,a,i,s=[],u=128;for(e===(0|e)?(r=e,e=null):(e+="\0",r=0,u=Math.max(u,e.length)),o=0,a=-32;a>>15,r^=r<<4,r^=r>>>13,a>=0&&(i=i+1640531527|0,o=0==(n=s[127&a]^=r+i)?o+1:0);for(o>=128&&(s[127&(e&&e.length||0)]=-1),o=127,a=512;a>0;--a)r=s[o+34&127],n=s[o=o+1&127],r^=r<<13,n^=n<<17,r^=r>>>15,n^=n>>>12,s[o]=r^n;t.w=i,t.X=s,t.i=o}(e,t)}function o(t,e){return e.i=t.i,e.w=t.w,e.X=t.X.slice(),e}function a(t,e){null==t&&(t=+new Date);var n=new r(t),a=e&&e.state,i=function(){return(n.next()>>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},i.int32=n.next,i.quick=i,a&&(a.X&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.xor4096=a}(0,t,!1)}),jn=zn(function(t){!function(t,e,n){function r(t){var e=this,n="";e.next=function(){var t=e.b,n=e.c,r=e.d,o=e.a;return t=t<<25^t>>>7^n,n=n-r|0,r=r<<24^r>>>8^o,o=o-t|0,e.b=t=t<<20^t>>>12^n,e.c=n=n-r|0,e.d=r<<16^n>>>16^o,e.a=o-t|0},e.a=0,e.b=0,e.c=-1640531527,e.d=1367130551,t===Math.floor(t)?(e.a=t/4294967296|0,e.b=0|t):n+=t;for(var r=0;r>>0)/4294967296};return i.double=function(){do{var t=((n.next()>>>11)+(n.next()>>>0)/4294967296)/(1<<21)}while(0===t);return t},i.int32=n.next,i.quick=i,a&&("object"==typeof a&&o(a,n),i.state=function(){return o(n,{})}),i}e&&e.exports?e.exports=a:n&&n.amd?n(function(){return a}):this.tychei=a}(0,t,!1)}),Xn=zn(function(t){!function(e,n){var r,o=this,a=256,i=6,s="random",u=n.pow(a,i),l=n.pow(2,52),c=2*l,h=a-1;function p(t,h,p){var g=[],y=v(function t(e,n){var r,o=[],a=typeof e;if(n&&"object"==a)for(r in e)try{o.push(t(e[r],n-1))}catch(t){}return o.length?o:"string"==a?e:e+"\0"}((h=1==h?{entropy:!0}:h||{}).entropy?[t,m(e)]:null==t?function(){try{var t;return r&&(t=r.randomBytes)?t=t(a):(t=new Uint8Array(a),(o.crypto||o.msCrypto).getRandomValues(t)),m(t)}catch(t){var n=o.navigator,i=n&&n.plugins;return[+new Date,o,i,o.screen,m(e)]}}():t,3),g),x=new f(g),b=function(){for(var t=x.g(i),e=u,n=0;t=c;)t/=2,e/=2,n>>>=1;return(t+n)/e};return b.int32=function(){return 0|x.g(4)},b.quick=function(){return x.g(4)/4294967296},b.double=b,v(m(x.S),e),(h.pass||p||function(t,e,r,o){return o&&(o.S&&d(o,x),t.state=function(){return d(x,{})}),r?(n[s]=t,e):t})(b,y,"global"in h?h.global:this==n,h.state)}function f(t){var e,n=t.length,r=this,o=0,i=r.i=r.j=0,s=r.S=[];for(n||(t=[n++]);o=1||0===i);var s=Math.sqrt(-2*Math.log(i)/i);e=this.mean+this.stdDev*o*s,n=this.mean+this.stdDev*a*s,this.truncated&&!this.isValidTruncated(e)||(r=!0)}return this.truncated&&!this.isValidTruncated(n)||(this.nextVal=this.convertValue(n)),this.convertValue(e)},t.prototype.convertValue=function(t){return null==this.dtype||"float32"===this.dtype?t:Math.round(t)},t.prototype.isValidTruncated=function(t){return t<=this.upper&&t>=this.lower},t}(),Jn=function(){function t(t,e,n,r){this.alpha=t,this.beta=1/e,this.dtype=n;var o=r||Math.random();this.randu=Yn(o.toString()),this.randn=new Qn(0,1,n,!1,this.randu()),this.d=t<1?t+2/3:t-1/3,this.c=1/Math.sqrt(9*this.d)}return t.prototype.nextValue=function(){for(var t,e,n,r,o,a;;){do{r=this.randn.nextValue(),a=1+this.c*r}while(a<=0);if(a*=a*a,e=1-.331*(t=r*r)*t,n=.5*t+this.d*(1-a+Math.log(a)),(o=this.randu())=1+e.length,function(){return"input rank is "+r.rank+" but should be > than blockShape.length "+e.length}),h(n.length===e.length,function(){return"crops.length is "+n.length+" but should be equal to blockShape.length "+e.length}),h(r.shape[0]%o==0,function(){return"input tensor batch is "+r.shape[0]+" but is not divisible by the product of the elements of blockShape "+e.join(" * ")+" === "+o}),kt.runKernel(function(t){return t.batchToSpaceND(r,e,n)},{$x:r},function(t){return{$x:function(){return t.spaceToBatchND(e,n)}}})}}),rr=mn({cast_:function(t,e){var n=rn(t,"x","cast");if(!S(e))throw new Error("Failed to cast to unknown dtype "+e);if("string"===e&&"string"!==n.dtype||"string"!==e&&"string"===n.dtype)throw new Error("Only strings can be casted to strings");return kt.runKernel(function(t){return t.cast(n,e)},{$x:n},function(t){return{$x:function(){return t.clone()}}})}}),or=mn({clone_:function(t){var e=rn(t,"x","clone",null);return kt.runKernel(function(t){return ut.make(e.shape,{dataId:e.dataId},e.dtype)},{$x:e},function(t){return{$x:function(){return t.toFloat()}}})}}),ar=mn({cumsum_:function(t,e,n,r){void 0===e&&(e=0),void 0===n&&(n=!1),void 0===r&&(r=!1);var o=rn(t,"x","cumsum"),a=hn([e|=0],o.rank),i=o;null!=a&&(i=o.transpose(a));var s=fn(1,o.rank)[0],u=kt.runKernel(function(t){return t.cumsum(i,s,n,r)},{permutedX:i},function(t){return{permutedX:function(){return t.cumsum(e,n,!r)}}});return null!=a&&(u=u.transpose(a)),u}}),ir=mn({depthToSpace_:function(t,e,n){void 0===n&&(n="NHWC");var r=rn(t,"x","depthToSpace"),o="NHWC"===n?r.shape[1]:r.shape[2],a="NHWC"===n?r.shape[2]:r.shape[3],i="NHWC"===n?r.shape[3]:r.shape[1];return h(o*e>=0,function(){return"Negative dimension size caused by overflow when multiplying\n "+o+" and "+e+" for depthToSpace with input shape\n "+r.shape}),h(a*e>=0,function(){return"Negative dimension size caused by overflow when multiplying\n "+a+" and "+e+" for depthToSpace with input shape\n "+r.shape}),h(i%(e*e)==0,function(){return"Dimension size must be evenly divisible by "+e*e+" but is "+i+" for depthToSpace with input shape "+r.shape}),kt.runKernel(function(t){return t.depthToSpace(r,e,n)},{$x:r})}}),sr=mn({expandDims_:function(t,e){void 0===e&&(e=0);var n=rn(t,"x","expandDims",null);h(e<=n.rank,function(){return"Axis must be <= rank of the tensor"});var r=n.shape.slice();return e<0&&(h(-(n.rank+1)<=e,function(){return"Axis must be in the interval ["+-(n.rank+1)+", "+n.rank+"]"}),e=n.rank+e+1),r.splice(e,0,1),br(n,r)}}),ur=mn({eye_:function(t,e,n,r){void 0===r&&(r="float32"),null==e&&(e=t);for(var o=tr([t,e],r),a=t<=e?t:e,i=0;i2)throw new Error("Rank of probabilities must be 1 or 2, but is "+i);n=n||Math.random();var s=1===i?o.as2D(1,-1):o,u=kt.runKernel(function(t){return t.multinomial(s,r,e,n)},{logits2D:s});return 1===i?u.as1D():u}}),cr=mn({oneHot_:function(t,e,n,r){if(void 0===n&&(n=1),void 0===r&&(r=0),e<2)throw new Error("Error in oneHot: depth must be >=2, but it is "+e);var o=rn(t,"indices","oneHot","int32"),a=o.shape.concat([e]);return o=o.flatten(),kt.runKernel(function(t){return t.oneHot(o,e,n,r)},{$indices:o},function(t){return{$indices:function(){return Tn(o.shape,"float32")}}}).reshape(a)}}),hr=mn({pad_:function(t,e,n){void 0===n&&(n=0);var r=rn(t,"x","pad");if(0===r.rank)throw new Error("pad(scalar) is not defined. Pass non-scalar to pad");var o=e.map(function(t){return t[0]});return kt.runKernel(function(t){return t.pad(r,e,n)},{$x:r},function(t){return{$x:function(){return t.slice(o,r.shape)}}})}}),pr=mn({pad1d_:function(t,e,n){return void 0===n&&(n=0),h(2===e.length,function(){return"Invalid number of paddings. Must be length of 2."}),hr(t,[e],n)}}),fr=mn({pad2d_:function(t,e,n){return void 0===n&&(n=0),h(2===e.length&&2===e[0].length&&2===e[1].length,function(){return"Invalid number of paddings. Must be length of 2 each."}),hr(t,e,n)}}),dr=mn({pad3d_:function(t,e,n){return void 0===n&&(n=0),h(3===e.length&&2===e[0].length&&2===e[1].length&&2===e[2].length,function(){return"Invalid number of paddings. Must be length of 2 each."}),hr(t,e,n)}}),vr=mn({pad4d_:function(t,e,n){return void 0===n&&(n=0),h(4===e.length&&2===e[0].length&&2===e[1].length&&2===e[2].length&&2===e[3].length,function(){return"Invalid number of paddings. Must be length of 2 each."}),hr(t,e,n)}}),mr=mn({rand_:function(t,e,n){var r=v(t),o=null;if(null==n||"float32"===n)o=new Float32Array(r);else if("int32"===n)o=new Int32Array(r);else{if("bool"!==n)throw new Error("Unknown data type "+n);o=new Uint8Array(r)}for(var a=0;a=1+e.length,function(){return"input rank "+r.rank+" should be > than [blockShape] "+e.length}),h(n.length===e.length,function(){return"paddings.shape[0] "+n.length+" must be equal to [blockShape] "+e.length}),h(r.shape.reduce(function(t,r,o){return o>0&&o<=e.length?t&&(r+n[o-1][0]+n[o-1][1])%e[o-1]==0:t},!0),function(){return"input spatial dimensions "+r.shape.slice(1)+" with paddings "+n.toString()+" must be divisible by blockShapes "+e.toString()}),kt.runKernel(function(t){return t.spaceToBatchND(r,e,n)},{$x:r},function(t){return{$x:function(){return t.batchToSpaceND(e,n)}}})}}),Cr=mn({squeeze_:function(t,e){var n=rn(t,"x","squeeze");return br(n,R(n.shape,e).newShape)}}),Er=mn({stack_:function(t,e){void 0===e&&(e=0);var n=on(t,"tensors","stack");if(h(n.length>=1,function(){return"Pass at least one tensor to tf.stack"}),1===n.length)return n[0].expandDims(e);var r=n[0].rank,o=n[0].shape,a=n[0].dtype;h(e<=r,function(){return"Axis must be <= rank of the tensor"}),n.forEach(function(t){p(o,t.shape,"All tensors passed to stack must have matching shapes")}),n.forEach(function(t){h(a===t.dtype,function(){return"All tensors passed to stack must have matching dtypes"})});var i=n.map(function(t){return t.expandDims(e)});return Bn(i,e)}}),Rr=mn({tile_:function(t,e){var n=rn(t,"x","tile",null);return h(n.rank===e.length,function(){return"Error in transpose: rank of input "+n.rank+" must match length of reps "+e+"."}),kt.runKernel(function(t,r){var o=t.tile(n,e);return r([n]),o},{$x:n},function(t,n){var r=n[0];return{$x:function(){var n=Mn(r);if(1===r.rank)for(var o=0;o=-n.shape.length&&e=2*e+1||o%2==1?i.push(o):a.push(o);r.push.apply(r,a),r.push(0),r.push.apply(r,i)}return r}function Tr(t,e,n,r){void 0===r&&(r=!0);var o=[];r?o.push(t[0]/n):o.push(t[0]*n);for(var a=1;at.rank)throw new Error("index innermost dimension length must be <= tensor rank; saw: "+e.shape[e.rank-1]+" vs. "+t.rank);if(0===t.size)throw new Error("Requested more than 0 entries, but input is empty. Input shape: "+t.shape+".");for(var n=e.shape,r=n[n.length-1],o=1,a=0;a1?e.shape[e.rank-1]:1,o=e.rank>1?e.rank-1:1,a="Must have updates.shape = indices.shape[:batchDim] + shape[sliceDim:], got updates.shape: "+n.shape+", indices.shape: "+e.shape+", shape: "+t+", sliceDim: "+r+", and batchDim: "+o+".";if(n.rank1?e.shape[e.rank-1]:1,o=n.length,a=1,i=r;i0;)1&t&&e.push(n),t/=2,n++;return e}function Wr(t,e,n){for(var r=[],o=0;o0?Number.MIN_SAFE_INTEGER:Number.MAX_SAFE_INTEGER);var s=r[o];return a<0&&(a+=s),a=u(0,a,s-1)}function Vr(t,e,n,r,o){var a=e[o],i=n[o]||1;(t&1<0?Number.MAX_SAFE_INTEGER:Number.MIN_SAFE_INTEGER);var s=r[o];return a<0&&(a+=s),a=i>0?u(0,a,s):u(-1,a,s-1)}function zr(t,e,n){for(var r=n.length,o=0;o1){r=o;break}for(o=r+1;o0||n[o]!==t[o])return!1;return!0}function Gr(t,e){for(var n=t.length>0?t[t.length-1]:1,r=0;r0,function(){return"variableGrads() expects at least one of the input variables to be trainable, but none of the "+a+" variables is trainable."});var i=kt.gradients(t,e,null,!0),s=i.value,u=i.grads;h(u.some(function(t){return null!=t}),function(){return"Cannot find a connection between any variable and the result of the loss function y=f(x). Please make sure the operations that use variables are inside the function f passed to minimize()."}),h(0===s.rank,function(){return"The f passed in variableGrads(f) must return a scalar, but it returned a rank-"+s.rank+" tensor"});var l={};return e.forEach(function(t,e){null!=u[e]&&(l[t.name]=u[e])}),null!=o&&o.forEach(function(t){return l[t.name]=null}),{value:s,grads:l}}function Xr(t){return kt.customGrad(t)}function Yr(t){if(t.filter(function(t){return null==t}).length>0)throw new Error("Cannot compute gradient of y=f(x) with respect to x. Make sure that\n the f you passed encloses all operations that lead from x to y.")}var Qr=mn({softmax_:function(t,e){void 0===e&&(e=-1);var n=rn(t,"logits","softmax");if(-1===e&&(e=n.rank-1),e!==n.rank-1)throw Error("Softmax along a non-last dimension is not yet supported. Logits was rank "+n.rank+" and dim was "+e);return Xr(function(t,n){var r=t.logSumExp([e],!0),o=t.toFloat().sub(r).exp();return n([o]),{value:o,gradFunc:function(t,n){var r=n[0],o=t.mul(r);return o.sub(o.sum([e],!0).mul(r))}}})(n)}}),Jr=mn({logSoftmax_:function(t,e){void 0===e&&(e=-1);var n=rn(t,"logits","logSoftmax");if(-1===e&&(e=n.rank-1),e!==n.rank-1)throw Error("Log Softmax along a non-last dimension is not yet supported. Logits was rank "+n.rank+" and axis was "+e);return Xr(function(t,n){var r=t.max(e,!0),o=t.sub(r),a=o.toFloat().sub(o.exp().sum(e,!0).log());return n([a]),{value:a,gradFunc:function(t,n){var r=n[0].exp();return t.sub(t.sum(e,!0).mul(r))}}})(n)}}),Zr=function(){function t(t,e){this.backend=t,this.dataMover=e,this.data=new WeakMap}return t.prototype.get=function(t){return this.data.has(t)||this.dataMover.moveData(this.backend,t),this.data.get(t)},t.prototype.set=function(t,e){this.data.set(t,e)},t.prototype.has=function(t){return this.data.has(t)},t.prototype.delete=function(t){return this.data.delete(t)},t}(),to=function(){function t(){}return t.prototype.time=function(t){throw new Error("Not yet implemented.")},t.prototype.read=function(t){throw new Error("Not yet implemented.")},t.prototype.readSync=function(t){throw new Error("Not yet implemented.")},t.prototype.disposeData=function(t){throw new Error("Not yet implemented.")},t.prototype.write=function(t,e){throw new Error("Not yet implemented.")},t.prototype.fromPixels=function(t,e){throw new Error("Not yet implemented.")},t.prototype.register=function(t,e,n){throw new Error("Not yet implemented.")},t.prototype.memory=function(){throw new Error("Not yet implemented.")},t.prototype.floatPrecision=function(){throw new Error("Not yet implemented")},t.prototype.epsilon=function(){return 32===this.floatPrecision()?1e-7:1e-4},t.prototype.batchMatMul=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.fusedBatchMatMul=function(t){t.a,t.b,t.transposeA,t.transposeB,t.bias,t.activation,t.preluActivationWeights;throw new Error("Not yet implemented")},t.prototype.slice=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.stridedSlice=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.unstack=function(t,e){throw new Error("Not yet implemented")},t.prototype.reverse=function(t,e){throw new Error("Not yet implemented")},t.prototype.concat=function(t,e){throw new Error("Not yet implemented")},t.prototype.neg=function(t){throw new Error("Not yet implemented")},t.prototype.add=function(t,e){throw new Error("Not yet implemented")},t.prototype.addN=function(t){throw new Error("Not yet implemented")},t.prototype.subtract=function(t,e){throw new Error("Not yet implemented")},t.prototype.multiply=function(t,e){throw new Error("Not yet implemented")},t.prototype.realDivide=function(t,e){throw new Error("Not yet implemented")},t.prototype.floorDiv=function(t,e){throw new Error("Not yet implemented")},t.prototype.sum=function(t,e){throw new Error("Not yet implemented")},t.prototype.prod=function(t,e){throw new Error("Not yet implemented")},t.prototype.unsortedSegmentSum=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.argMin=function(t,e){throw new Error("Not yet implemented")},t.prototype.argMax=function(t,e){throw new Error("Not yet implemented")},t.prototype.equal=function(t,e){throw new Error("Not yet implemented")},t.prototype.notEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.less=function(t,e){throw new Error("Not yet implemented")},t.prototype.lessEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.greater=function(t,e){throw new Error("Not yet implemented")},t.prototype.greaterEqual=function(t,e){throw new Error("Not yet implemented")},t.prototype.logicalNot=function(t){throw new Error("Not yet implemented")},t.prototype.logicalAnd=function(t,e){throw new Error("Not yet implemented")},t.prototype.logicalOr=function(t,e){throw new Error("Not yet implemented")},t.prototype.where=function(t){throw new Error("Not yet implemented")},t.prototype.select=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.topk=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.min=function(t,e){throw new Error("Not yet implemented")},t.prototype.minimum=function(t,e){throw new Error("Not yet implemented")},t.prototype.mod=function(t,e){throw new Error("Not yet implemented")},t.prototype.max=function(t,e){throw new Error("Not yet implemented")},t.prototype.maximum=function(t,e){throw new Error("Not yet implemented")},t.prototype.all=function(t,e){throw new Error("Not yet implemented")},t.prototype.any=function(t,e){throw new Error("Not yet implemented")},t.prototype.squaredDifference=function(t,e){throw new Error("Not yet implemented")},t.prototype.ceil=function(t){throw new Error("Not yet implemented")},t.prototype.floor=function(t){throw new Error("Not yet implemented")},t.prototype.round=function(t){throw new Error("Not yet implemented")},t.prototype.sign=function(t){throw new Error("Not yet implemented")},t.prototype.isNaN=function(t){throw new Error("Not yet implemented")},t.prototype.isInf=function(t){throw new Error("Not yet implemented")},t.prototype.isFinite=function(t){throw new Error("Not yet implemented")},t.prototype.pow=function(t,e){throw new Error("Not yet implemented")},t.prototype.exp=function(t){throw new Error("Not yet implemented")},t.prototype.expm1=function(t){throw new Error("Not yet implemented")},t.prototype.log=function(t){throw new Error("Not yet implemented")},t.prototype.log1p=function(t){throw new Error("Not yet implemented")},t.prototype.sqrt=function(t){throw new Error("Not yet implemented")},t.prototype.rsqrt=function(t){throw new Error("Not yet implemented")},t.prototype.square=function(t){throw new Error("Not yet implemented")},t.prototype.reciprocal=function(t){throw new Error("Not yet implemented")},t.prototype.relu=function(t){throw new Error("Not yet implemented")},t.prototype.relu6=function(t){throw new Error("Not yet implemented")},t.prototype.prelu=function(t,e){throw new Error("Not yet implemented")},t.prototype.elu=function(t){throw new Error("Not yet implemented")},t.prototype.eluDer=function(t,e){throw new Error("Not yet implemented")},t.prototype.selu=function(t){throw new Error("Not yet implemented")},t.prototype.int=function(t){throw new Error("Not yet implemented")},t.prototype.clip=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.abs=function(t){throw new Error("Not yet implemented")},t.prototype.complexAbs=function(t){throw new Error("Not yet implemented")},t.prototype.sigmoid=function(t){throw new Error("Not yet implemented")},t.prototype.softplus=function(t){throw new Error("Not yet implemented")},t.prototype.sin=function(t){throw new Error("Not yet implemented")},t.prototype.cos=function(t){throw new Error("Not yet implemented")},t.prototype.tan=function(t){throw new Error("Not yet implemented")},t.prototype.asin=function(t){throw new Error("Not yet implemented")},t.prototype.acos=function(t){throw new Error("Not yet implemented")},t.prototype.atan=function(t){throw new Error("Not yet implemented")},t.prototype.atan2=function(t,e){throw new Error("Not yet implemented")},t.prototype.sinh=function(t){throw new Error("Not yet implemented")},t.prototype.cosh=function(t){throw new Error("Not yet implemented")},t.prototype.tanh=function(t){throw new Error("Not yet implemented")},t.prototype.asinh=function(t){throw new Error("Not yet implemented")},t.prototype.acosh=function(t){throw new Error("Not yet implemented")},t.prototype.atanh=function(t){throw new Error("Not yet implemented")},t.prototype.erf=function(t){throw new Error("Not yet implemented")},t.prototype.step=function(t,e){throw new Error("Not yet implemented")},t.prototype.fusedConv2d=function(t){t.input,t.filter,t.convInfo,t.bias,t.activation,t.preluActivationWeights;throw new Error("Not yet implemented")},t.prototype.conv2d=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv2dDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv2dDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.fusedDepthwiseConv2D=function(t){t.input,t.filter,t.convInfo,t.bias,t.activation,t.preluActivationWeights;throw new Error("Not yet implemented")},t.prototype.depthwiseConv2D=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.depthwiseConv2DDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.depthwiseConv2DDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3d=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3dDerInput=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.conv3dDerFilter=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.maxPool=function(t,e){throw new Error("Not yet implemented")},t.prototype.maxPoolBackprop=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.avgPool=function(t,e){throw new Error("Not yet implemented")},t.prototype.avgPoolBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.avgPool3d=function(t,e){throw new Error("Not yet implemented")},t.prototype.avgPool3dBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.maxPool3d=function(t,e){throw new Error("Not yet implemented")},t.prototype.maxPool3dBackprop=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.reshape=function(t,e){throw new Error("Not yet implemented")},t.prototype.cast=function(t,e){throw new Error("Not yet implemented")},t.prototype.tile=function(t,e){throw new Error("Not yet implemented")},t.prototype.pad=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.transpose=function(t,e){throw new Error("Not yet implemented")},t.prototype.gather=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.gatherND=function(t,e){throw new Error("Not yet implemented")},t.prototype.scatterND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.batchToSpaceND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.spaceToBatchND=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.resizeBilinear=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.resizeBilinearBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.resizeNearestNeighbor=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.resizeNearestNeighborBackprop=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.batchNormalization=function(t,e,n,r,o,a){throw new Error("Not yet implemented")},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){throw new Error("Not yet implemented")},t.prototype.LRNGrad=function(t,e,n,r,o,a,i){throw new Error("Not yet implemented")},t.prototype.multinomial=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.oneHot=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.cumsum=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.nonMaxSuppression=function(t,e,n,r,o){throw new Error("Not yet implemented")},t.prototype.fft=function(t){throw new Error("Not yet implemented")},t.prototype.ifft=function(t){throw new Error("Not yet implemented")},t.prototype.complex=function(t,e){throw new Error("Not yet implemented")},t.prototype.real=function(t){throw new Error("Not yet implemented")},t.prototype.imag=function(t){throw new Error("Not yet implemented")},t.prototype.cropAndResize=function(t,e,n,r,o,a){throw new Error("Not yet implemented")},t.prototype.depthToSpace=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.split=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.sparseToDense=function(t,e,n,r){throw new Error("Not yet implemented")},t.prototype.diag=function(t){throw new Error("Not yet implemented")},t.prototype.fill=function(t,e,n){throw new Error("Not yet implemented.")},t.prototype.onesLike=function(t){throw new Error("Not yet implemented")},t.prototype.zerosLike=function(t){throw new Error("Not yet implemented")},t.prototype.linspace=function(t,e,n){throw new Error("Not yet implemented")},t.prototype.dispose=function(){throw new Error("Not yet implemented")},t}();function eo(t,e){for(var n=t.length,r=[],o=0;o1&&1===i&&r.unshift(a)}return r}function no(t,e){for(var n=[],r=0;r1)&&n.unshift(a)}return n}function ro(t,e){for(var n=[],r=Math.max(t.length,e.length),o=0;oo}).sort(function(t,e){return e.score-t.score}),i=[],s=0;s=0;--p){if(ko(t,c,i[p])>=r){h=!0;break}}if(!h&&(i.push(c),i.length>=n))break}return En(i,"int32")}function ko(t,e,n){var r=t.subarray(4*e,4*e+4),o=t.subarray(4*n,4*n+4),a=Math.min(r[0],r[2]),i=Math.min(r[1],r[3]),s=Math.max(r[0],r[2]),u=Math.max(r[1],r[3]),l=Math.min(o[0],o[2]),c=Math.min(o[1],o[3]),h=Math.max(o[0],o[2]),p=Math.max(o[1],o[3]),f=(s-a)*(u-i),d=(h-l)*(p-c);if(f<=0||d<=0)return 0;var v=Math.max(a,l),m=Math.max(i,c),g=Math.min(s,h),y=Math.min(u,p),x=Math.max(g-v,0)*Math.max(y-m,0);return x/(f+d-x)}function No(t,e,n){var r=new Array(t.rank).fill(0),o=t.shape.slice();return e.map(function(e){o[n]=e;var a=t.slice(r,o);return r[n]+=e,a})}function So(t,e){for(var n=new Array(t.rank),r=0;r":"<",u=n?"inOffset + i;":"round(getBestIndicesA(batch, inOffset + i));";this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * "+r+";\n\n int bestIndex = inOffset;\n float bestValue = getA(batch, bestIndex);\n\n for (int i = 0; i < "+r+"; i++) {\n int inIdx = "+u+";\n float candidate = getA(batch, inIdx);\n if (candidate "+s+" bestValue) {\n bestValue = candidate;\n bestIndex = inIdx;\n }\n }\n setOutput(float(bestIndex));\n }\n "}}();function Fo(t,e){return["x","y","z","w","u","v"].slice(0,e).map(function(e){return t+"."+e})}function Mo(t,e){return 1===e?[t]:Fo(t,e)}function Bo(){var t,e,n,r,o,i,s,u,l,c;return 2===a().getNumber("WEBGL_VERSION")?(t="#version 300 es",e="in",n="out",r="in",o="texture",i="outputColor",s="out vec4 outputColor;",u="\n bool isnan_custom(float val) {\n return (val > 0.0 || val < 0.0) ? false : val != 0.0;\n }\n\n bvec4 isnan_custom(vec4 val) {\n return bvec4(isnan_custom(val.x),\n isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w));\n }\n\n #define isnan(value) isnan_custom(value)\n ",l="",c="\n #define round(value) newRound(value)\n int newRound(float value) {\n return int(floor(value + 0.5));\n }\n\n ivec4 newRound(vec4 value) {\n return ivec4(floor(value + vec4(0.5)));\n }\n "):(t="",e="attribute",n="varying",r="varying",o="texture2D",i="gl_FragColor",s="",u="\n #define isnan(value) isnan_custom(value)\n bool isnan_custom(float val) {\n return (val > 0. || val < 1. || val == 0.) ? false : true;\n }\n bvec4 isnan_custom(vec4 val) {\n return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));\n }\n ",l="\n uniform float INFINITY;\n\n bool isinf(float val) {\n return abs(val) == INFINITY;\n }\n bvec4 isinf(vec4 val) {\n return equal(abs(val), vec4(INFINITY));\n }\n ",c="\n int round(float value) {\n return int(floor(value + 0.5));\n }\n\n ivec4 round(vec4 value) {\n return ivec4(floor(value + vec4(0.5)));\n }\n "),{version:t,attribute:e,varyingVs:n,varyingFs:r,texture2D:o,output:i,defineOutput:s,defineSpecialNaN:u,defineSpecialInf:l,defineRound:c}}function Po(t,e,n){void 0===n&&(n="index");var r=W(e);return r.map(function(e,o){return"int "+t[o]+" = "+n+" / "+e+"; "+(o===r.length-1?"int "+t[o+1]+" = "+n+" - "+t[o]+" * "+e:"index -= "+t[o]+" * "+e)+";"}).join("")}function Lo(t){var e=W(t).map(function(t){return t.toString()});return"\n int getFlatIndex(ivec3 coords) {\n return coords.x * "+e[0]+" + coords.y * "+e[1]+" + coords.z;\n }\n"}var Wo="\n const float FLOAT_MAX = 1.70141184e38;\n const float FLOAT_MIN = 1.17549435e-38;\n\n lowp vec4 encode_float(highp float v) {\n if (isnan(v)) {\n return vec4(255, 255, 255, 255);\n }\n\n highp float av = abs(v);\n\n if(av < FLOAT_MIN) {\n return vec4(0.0, 0.0, 0.0, 0.0);\n } else if(v > FLOAT_MAX) {\n return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;\n } else if(v < -FLOAT_MAX) {\n return vec4(0.0, 0.0, 128.0, 255.0) / 255.0;\n }\n\n highp vec4 c = vec4(0,0,0,0);\n\n highp float e = floor(log2(av));\n highp float m = exp2(fract(log2(av))) - 1.0;\n\n c[2] = floor(128.0 * m);\n m -= c[2] / 128.0;\n c[1] = floor(32768.0 * m);\n m -= c[1] / 32768.0;\n c[0] = floor(8388608.0 * m);\n\n highp float ebias = e + 127.0;\n c[3] = floor(ebias / 2.0);\n ebias -= c[3] * 2.0;\n c[2] += floor(ebias) * 128.0;\n\n c[3] += 128.0 * step(0.0, -v);\n\n return c / 255.0;\n }\n";function Uo(t,e,n,r){var o=[];t.forEach(function(t){var e=v(t.shapeInfo.logicalShape);t.shapeInfo.isUniform?o.push("uniform float "+t.name+(e>1?"["+e+"]":"")+";"):(o.push("uniform sampler2D "+t.name+";"),o.push("uniform int offset"+t.name+";"))});var a,i,s=o.join("\n"),u=t.map(function(t){return function(t,e,n){void 0===n&&(n=!1);var r="";r+=n?zo(t):Vo(t);var o=t.shapeInfo.logicalShape,a=e.logicalShape;o.length<=a.length&&(r+=n?function(t,e){var n,r=t.name,o=r.charAt(0).toUpperCase()+r.slice(1),a="get"+o+"AtOutCoords",i=t.shapeInfo.logicalShape.length,s=e.logicalShape.length,u=eo(t.shapeInfo.logicalShape,e.logicalShape),l=Xo(s),c=s-i,h=["x","y","z","w","u","v"];n=0===i?"":s<2&&u.length>=1?"coords = 0;":u.map(function(t){return"coords."+h[t+c]+" = 0;"}).join("\n");var p="";p=s<2&&i>0?"coords":t.shapeInfo.logicalShape.map(function(t,e){return"coords."+h[e+c]}).join(", ");var f="return outputValue;",d=1===v(t.shapeInfo.logicalShape),m=1===v(e.logicalShape);if(1!==i||d||m){if(d&&!m)f=1===s?"\n return vec4(outputValue.x, outputValue.x, 0., 0.);\n ":"\n return vec4(outputValue.x);\n ";else if(u.length){var g=i-2,y=i-1;u.indexOf(g)>-1&&u.indexOf(y)>-1?f="return vec4(outputValue.x);":u.indexOf(g)>-1?f="return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);":u.indexOf(y)>-1&&(f="return vec4(outputValue.xx, outputValue.zz);")}}else f="\n return vec4(outputValue.xy, outputValue.xy);\n ";return"\n vec4 "+a+"() {\n "+l+" coords = getOutputCoords();\n "+n+"\n vec4 outputValue = get"+o+"("+p+");\n "+f+"\n }\n "}(t,e):function(t,e){var n=t.name,r=n.charAt(0).toUpperCase()+n.slice(1),o="get"+r+"AtOutCoords",a=e.texShape,i=t.shapeInfo.texShape,s=t.shapeInfo.logicalShape.length,u=e.logicalShape.length;if(!t.shapeInfo.isUniform&&s===u&&null==t.shapeInfo.flatOffset&&m(i,a))return"\n float "+o+"() {\n return sampleTexture("+n+", resultUV);\n }\n ";var l,c=Xo(u),h=eo(t.shapeInfo.logicalShape,e.logicalShape),p=u-s,f=["x","y","z","w","u","v"];l=0===s?"":u<2&&h.length>=1?"coords = 0;":h.map(function(t){return"coords."+f[t+p]+" = 0;"}).join("\n");var d="";d=u<2&&s>0?"coords":t.shapeInfo.logicalShape.map(function(t,e){return"coords."+f[e+p]}).join(", ");return"\n float "+o+"() {\n "+c+" coords = getOutputCoords();\n "+l+"\n return get"+r+"("+d+");\n }\n "}(t,e));return r}(t,e,r)}).join("\n"),l=e.texShape,c=Bo(),h=function(t){return"\n float sampleTexture(sampler2D textureSampler, vec2 uv) {\n return "+t.texture2D+"(textureSampler, uv).r;\n }\n "}(c),p=function(t){return t.version+"\n precision highp float;\n precision highp int;\n precision highp sampler2D;\n "+t.varyingFs+" vec2 resultUV;\n "+t.defineOutput+"\n const vec2 halfCR = vec2(0.5, 0.5);\n\n struct ivec5\n {\n int x;\n int y;\n int z;\n int w;\n int u;\n };\n\n struct ivec6\n {\n int x;\n int y;\n int z;\n int w;\n int u;\n int v;\n };\n\n uniform float NAN;\n "+t.defineSpecialNaN+"\n "+t.defineSpecialInf+"\n "+t.defineRound+"\n\n int imod(int x, int y) {\n return x - y * (x / y);\n }\n\n int idiv(int a, int b, float sign) {\n int res = a / b;\n int mod = imod(a, b);\n if (sign < 0. && mod != 0) {\n res -= 1;\n }\n return res;\n }\n\n //Based on the work of Dave Hoskins\n //https://www.shadertoy.com/view/4djSRW\n #define HASHSCALE1 443.8975\n float random(float seed){\n vec2 p = resultUV * seed;\n vec3 p3 = fract(vec3(p.xyx) * HASHSCALE1);\n p3 += dot(p3, p3.yzx + 19.19);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n "+Go+"\n "+Ho+"\n "+qo+"\n "}(c);return e.isPacked?(a=function(t,e){switch(t.length){case 0:return"\n int getOutputCoords() {\n return 0;\n }\n ";case 1:return function(t,e){var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)];if(1===n[0])return"\n int getOutputCoords() {\n return 2 * int(resultUV.x * "+n[1]+".0);\n }\n ";if(1===n[1])return"\n int getOutputCoords() {\n return 2 * int(resultUV.y * "+n[0]+".0);\n }\n ";return"\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+n[0]+", "+n[1]+"));\n return 2 * (resTexRC.x * "+n[1]+" + resTexRC.y);\n }\n "}(0,e);case 2:return function(t,e){var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)];if(m(t,e))return"\n ivec2 getOutputCoords() {\n return 2 * ivec2(resultUV.yx * vec2("+n[0]+", "+n[1]+"));\n }\n ";var r=Math.ceil(t[1]/2);return"\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+n[0]+", "+n[1]+"));\n\n int index = resTexRC.x * "+n[1]+" + resTexRC.y;\n int r = 2 * (index / "+r+");\n int c = imod(index, "+r+") * 2;\n\n return ivec2(r, c);\n }\n "}(t,e);case 3:return n=t,r=e,o=[Math.ceil(r[0]/2),Math.ceil(r[1]/2)],a=Math.ceil(n[2]/2),i=a*Math.ceil(n[1]/2),"\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+o[0]+", "+o[1]+"));\n int index = resTexRC.x * "+o[1]+" + resTexRC.y;\n\n int b = index / "+i+";\n index -= b * "+i+";\n\n int r = 2 * (index / "+a+");\n int c = imod(index, "+a+") * 2;\n\n return ivec3(b, r, c);\n }\n ";default:return function(t,e){for(var n=[Math.ceil(e[0]/2),Math.ceil(e[1]/2)],r=Math.ceil(t[t.length-1]/2),o=r*Math.ceil(t[t.length-2]/2),a=o,i="",s="b, r, c",u=2;u2,function(){return"Packed arg"+(n.charAt(0).toUpperCase()+n.slice(1))+" supports only inputs with rank above 2."});var o=t[t.length-1],a=Math.ceil(o/e);this.outputShape=t.slice(0,-1),a>1&&this.outputShape.push(a),r||this.variableNames.push("bestIndicesA");var i,s,u=this.outputShape,l=u.length,c=Xo(l),p=Mo("coords",l);if(1===a){var f=Xo(s=l+1);i="\n "+f+" sourceLocR = "+f+"("+p.join()+", 0);\n ++"+p[l-1]+";\n "+f+" sourceLocG = "+f+"("+p.join()+", 0);\n ++"+p[l-2]+";\n "+f+" sourceLocA = "+f+"("+p.join()+", 0);\n --"+p[l-1]+";\n "+f+" sourceLocB = "+f+"("+p.join()+", 0);\n --"+p[l-2]+";"}else s=l,i="\n "+c+" sourceLocR = coords;\n ++"+p[l-1]+";\n "+c+" sourceLocG = coords;\n ++"+p[l-2]+";\n "+c+" sourceLocA = coords;\n --"+p[l-1]+";\n "+c+" sourceLocB = coords;\n --"+p[l-2]+";";var d=["x","y","z","w","u","v"].slice(0,s),v="."+d[s-1],m=d.map(function(t){return"int "+t}),g=Mo("sourceLocR",s-1).concat("inIdx.r"),y=Mo("sourceLocG",s-1).concat("inIdx.g"),x=Mo("sourceLocB",s-1).concat("inIdx.b"),b=Mo("sourceLocA",s-1).concat("inIdx.a"),w="max"===n?"greaterThan":"lessThan",C=r?"":"\n inIdx = round(vec4(getBestIndicesAChannel("+g.join()+"),\n getBestIndicesAChannel("+y.join()+"),\n getBestIndicesAChannel("+x.join()+"),\n getBestIndicesAChannel("+b.join()+")));",E="vec4(\n getAChannel("+g.join()+"),\n hasNextCol ? getAChannel("+y.join()+") : 0.,\n hasNextRow ? getAChannel("+x.join()+") : 0.,\n hasNextRow && hasNextCol ? getAChannel("+b.join()+") : 0.)",R=r?"":"\n float getBestIndicesAChannel("+m.join()+") {\n return getChannel(getBestIndicesA("+d.join()+"),\n vec2("+d.slice(-2).join()+"));\n }";this.userCode="\n float getAChannel("+m.join()+") {\n return getChannel(getA("+d.join()+"),\n vec2("+d.slice(-2).join()+"));\n }\n "+R+"\n void main() {\n "+c+" coords = getOutputCoords();\n bool hasNextCol = "+p[l-1]+" < "+(u[l-1]-1)+";\n bool hasNextRow = "+p[l-2]+" < "+(u[l-2]-1)+";\n "+i+"\n ivec4 srcIdx = ivec4(sourceLocR"+v+", sourceLocG"+v+",\n sourceLocB"+v+", sourceLocA"+v+") * "+e+";\n ivec4 inIdx = srcIdx;\n vec4 bestIndex = vec4(inIdx);\n vec4 bestValue = "+E+";\n\n for (int i = 0; i < "+e+"; i++) {\n inIdx = srcIdx;\n "+C+"\n vec4 candidate = "+E+";\n bvec4 nan = isnan(candidate);\n bvec4 replace = bvec4(\n vec4("+w+"(candidate, bestValue)) * (vec4(1.0) - vec4(nan)));\n\n bestValue = vec4(replace.x ? candidate.x : bestValue.x,\n replace.y ? candidate.y : bestValue.y,\n replace.z ? candidate.z : bestValue.z,\n replace.w ? candidate.w : bestValue.w);\n bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace));\n srcIdx++;\n }\n setOutput(bestIndex);\n }\n "}}(),Zo=function(){return function(t){this.variableNames=["dy"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a=t.dilationHeight,i=t.dilationWidth,s=t.effectiveFilterHeight,u=t.effectiveFilterWidth,l=s-1-t.padInfo.top,c=u-1-t.padInfo.left,h=1/(e*n);this.userCode="\n const ivec2 pads = ivec2("+l+", "+c+");\n const float avgMultiplier = float("+h+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n\n ivec2 dyRCCorner = coords.yz - pads;\n int dyRCorner = dyRCCorner.x;\n int dyCCorner = dyRCCorner.y;\n\n // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+s+";\n wR += "+a+") {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+u+";\n wC+= "+i+") {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(b, idyR, idyC, d);\n\n dotProd += dyValue * avgMultiplier;\n }\n }\n setOutput(dotProd);\n }\n "}}(),ta=function(){return function(t){this.variableNames=["dy"],this.outputShape=t.inShape;var e=t.filterDepth,n=t.filterHeight,r=t.filterWidth,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=t.dilationDepth,u=t.dilationHeight,l=t.dilationWidth,c=t.effectiveFilterDepth,h=t.effectiveFilterHeight,p=t.effectiveFilterWidth,f=c-1-t.padInfo.front,d=h-1-t.padInfo.top,v=p-1-t.padInfo.left,m=1/(e*n*r);this.userCode="\n const ivec3 pads = ivec3("+f+", "+d+", "+v+");\n const float avgMultiplier = float("+m+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyDCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n // Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get\n // dx(xD, xR, xC, ch).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int wD = 0; wD < "+c+";\n wD += "+s+") {\n float dyD = float(dyDCorner + wD) / "+o+".0;\n\n if (dyD < 0.0 || dyD >= "+t.outDepth+".0 || fract(dyD) > 0.0) {\n continue;\n }\n int idyD = int(dyD);\n\n for (int wR = 0; wR < "+h+";\n wR += "+u+") {\n float dyR = float(dyRCorner + wR) / "+a+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+p+";\n wC += "+l+") {\n float dyC = float(dyCCorner + wC) / "+i+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n\n dotProd += dyValue * avgMultiplier;\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),ea=function(){return function(t,e,n,r,o,a){this.outputShape=[],this.variableNames=["x","mean","variance"],ro(t,e),ro(t,n);var i="0.0";null!=r&&(ro(t,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");var s="1.0";null!=o&&(ro(t,o),this.variableNames.push("scale"),s="getScaleAtOutCoords()"),this.outputShape=t,this.userCode="\n void main() {\n float x = getXAtOutCoords();\n float mean = getMeanAtOutCoords();\n float variance = getVarianceAtOutCoords();\n float offset = "+i+";\n float scale = "+s+";\n float inv = scale * inversesqrt(variance + float("+a+"));\n setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));\n }\n "}}(),na=function(){return function(t,e,n,r,o,a){this.usesPackedTextures=!0,this.variableNames=["x","mean","variance"],ro(t,e),ro(t,n);var i="vec4(0.0)";null!=r&&(ro(t,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");var s="vec4(1.0)";null!=o&&(ro(t,o),this.variableNames.push("scale"),s="getScaleAtOutCoords()"),this.outputShape=t,this.userCode="\n void main() {\n vec4 offset = "+i+";\n vec4 scale = "+s+";\n\n vec4 x = getXAtOutCoords();\n vec4 mean = getMeanAtOutCoords();\n vec4 variance = getVarianceAtOutCoords();\n\n vec4 inv = scale * inversesqrt(variance + vec4("+a+"));\n\n setOutput((x - mean) * inv + offset);\n }\n "}}(),ra="return areal * breal - aimag * bimag;",oa="return areal * bimag + aimag * breal;",aa=function(){return function(t,e,n){this.variableNames=["AReal","AImag","BReal","BImag"],this.outputShape=ro(e,n),this.userCode="\n float binaryOpComplex(\n float areal, float aimag, float breal, float bimag) {\n "+t+"\n }\n\n void main() {\n float areal = getARealAtOutCoords();\n float aimag = getAImagAtOutCoords();\n float breal = getBRealAtOutCoords();\n float bimag = getBImagAtOutCoords();\n setOutput(binaryOpComplex(areal, aimag, breal, bimag));\n }\n "}}(),ia="return a + b;",sa="return a - b;",ua="return a * b;",la="return (a < 0.) ? b * a : a;",ca=function(){return function(t,e,n){this.variableNames=["A","B"],this.outputShape=ro(e,n),this.userCode="\n float binaryOperation(float a, float b) {\n "+t+"\n }\n\n void main() {\n float a = getAAtOutCoords();\n float b = getBAtOutCoords();\n setOutput(binaryOperation(a, b));\n }\n "}}(),ha="\n vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n",pa=function(){return function(t,e,n,r){void 0===r&&(r=!1),this.variableNames=["A","B"],this.supportsBroadcasting=!0,this.usesPackedTextures=!0,this.outputShape=ro(e,n);var o=this.outputShape.length,a="";if(r)if(0===o||1===v(this.outputShape))a="\n result.y = 0.;\n result.z = 0.;\n result.w = 0.;\n ";else if(a="\n "+Xo(o)+" coords = getOutputCoords();\n ",1===o)a+="\n result.y = (coords + 1) >= "+this.outputShape[0]+" ? 0. : result.y;\n result.z = 0.;\n result.w = 0.;\n ";else{var i=Mo("coords",o);a+="\n bool nextRowOutOfBounds =\n ("+i[o-2]+" + 1) >= "+this.outputShape[o-2]+";\n bool nextColOutOfBounds =\n ("+i[o-1]+" + 1) >= "+this.outputShape[o-1]+";\n result.y = nextColOutOfBounds ? 0. : result.y;\n result.z = nextRowOutOfBounds ? 0. : result.z;\n result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;\n "}this.userCode="\n vec4 binaryOperation(vec4 a, vec4 b) {\n "+t+"\n }\n\n void main() {\n vec4 a = getAAtOutCoords();\n vec4 b = getBAtOutCoords();\n\n vec4 result = binaryOperation(a, b);\n "+a+"\n\n setOutput(result);\n }\n "}}(),fa=function(){function t(t){this.variableNames=["A"],this.outputShape=t,this.userCode="\n uniform float minVal;\n uniform float maxVal;\n\n void main() {\n float value = getAAtOutCoords();\n if (isnan(value)) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, minVal, maxVal));\n }\n "}return t.prototype.getCustomSetupFunc=function(t,e){var n=this;return function(r,o){null==n.minLoc&&(n.minLoc=r.getUniformLocationNoThrow(o,"minVal"),n.maxLoc=r.getUniformLocationNoThrow(o,"maxVal")),r.gl.uniform1f(n.minLoc,t),r.gl.uniform1f(n.maxLoc,e)}},t}(),da=function(){function t(t){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t,this.userCode="\n uniform float minVal;\n uniform float maxVal;\n\n void main() {\n vec4 value = getAAtOutCoords();\n\n if (any(isnan(value))) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, vec4(minVal), vec4(maxVal)));\n }\n "}return t.prototype.getCustomSetupFunc=function(t,e){var n=this;return function(r,o){null==n.minLoc&&(n.minLoc=r.getUniformLocationNoThrow(o,"minVal"),n.maxLoc=r.getUniformLocationNoThrow(o,"maxVal")),r.gl.uniform1f(n.minLoc,t),r.gl.uniform1f(n.maxLoc,e)}},t}(),va=function(){return function(t){this.variableNames=["real","imag"],this.outputShape=t,this.userCode="\n void main() {\n float re = abs(getRealAtOutCoords());\n float im = abs(getImagAtOutCoords());\n float mx = max(re, im);\n\n // sadly the length function in glsl is not underflow-safe\n // (at least not on Intel GPUs). So the safe solution is\n // to ensure underflow-safety in all cases.\n setOutput(\n mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx))\n );\n }\n "}}(),ma=function(){return function(t){this.outputShape=[],this.outputShape=vn(t,1),this.variableNames=t.map(function(t,e){return"T"+e});var e=new Array(t.length-1);e[0]=t[0][1];for(var n=1;n= "+s[u-1]+") {\n return getChannel(\n getT"+u+"("+ya(i,l,f)+"),\n vec2("+ya(c,l,f)+"));\n }"}var d=s.length,v=s[s.length-1];p+="\n return getChannel(\n getT"+d+"("+ya(i,l,v)+"),\n vec2("+ya(c,l,v)+"));",this.userCode="\n float getValue("+i.map(function(t){return"int "+t})+") {\n "+p+"\n }\n\n void main() {\n "+o+" coords = getOutputCoords();\n vec4 result = vec4(getValue("+a+"), 0., 0., 0.);\n\n "+a[r-1]+" = "+a[r-1]+" + 1;\n if ("+a[r-1]+" < "+n[r-1]+") {\n result.g = getValue("+a+");\n }\n\n "+a[r-2]+" = "+a[r-2]+" + 1;\n if ("+a[r-2]+" < "+n[r-2]+") {\n result.a = getValue("+a+");\n }\n\n "+a[r-1]+" = "+a[r-1]+" - 1;\n if ("+a[r-2]+" < "+n[r-2]+" &&\n "+a[r-1]+" < "+n[r-1]+") {\n result.b = getValue("+a+");\n }\n setOutput(result);\n }\n "}}();function ya(t,e,n){var r=t.indexOf(e);return t.map(function(t,e){return e===r?t+" - "+n:t}).join()}var xa=function(){return function(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;var e=t.strideHeight,n=t.strideWidth,r=t.padInfo.top,o=t.padInfo.left,a="channelsLast"===t.dataFormat;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int wR = coords.x;\n int wC = coords.y;\n int d1 = coords.z;\n int d2 = coords.w;\n\n // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int b = 0; b < "+t.batchSize+"; b++) {\n for (int yR = 0; yR < "+t.outHeight+"; yR++) {\n int xR = wR + yR * "+e+" - "+r+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+n+" - "+o+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n if ("+a+") {\n float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);\n } else {\n float dyValue = getDy(b, d2, yR, yC);\n float xValue = getX(b, d1, xR, xC);\n dotProd += (xValue * dyValue);\n }\n\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),ba=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a="channelsLast"===t.dataFormat,i=e-1-t.padInfo.top,s=n-1-t.padInfo.left,u=a?1:2,l=a?2:3,c=a?3:1;this.userCode="\n const ivec2 pads = ivec2("+i+", "+s+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords["+c+"];\n\n ivec2 dyCorner = ivec2(coords["+u+"], coords["+l+"]) - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+e+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+e+" - 1 - wR;\n\n for (int wC = 0; wC < "+n+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+n+" - 1 - wC;\n\n for (int d2 = 0; d2 < "+t.outChannels+"; d2++) {\n\n if ("+a+") {\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n } else {\n float xValue = getDy(batch, d2, idyR, idyC);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),wa=function(){return function(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;var e=t.strideDepth,n=t.strideHeight,r=t.strideWidth,o=t.padInfo.front,a=t.padInfo.top,i=t.padInfo.left;this.userCode="\n void main() {\n ivec5 coords = getOutputCoords();\n int wF = coords.x;\n int wR = coords.y;\n int wC = coords.z;\n int d1 = coords.w;\n int d2 = coords.u;\n\n float dotProd = 0.0;\n\n for (int b = 0; b < "+t.batchSize+"; b++) {\n for (int yF = 0; yF < "+t.outDepth+"; yF++) {\n int xF = wF + yF * "+e+" - "+o+";\n\n if (xF < 0 || xF >= "+t.inDepth+") {\n continue;\n }\n\n for (int yR = 0; yR < "+t.outHeight+"; yR++) {\n int xR = wR + yR * "+n+" - "+a+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+r+" - "+i+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float dyValue = getDy(b, yF, yR, yC, d2);\n float xValue = getX(b, xF, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),Ca=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterDepth,n=t.filterHeight,r=t.filterWidth,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=e-1-t.padInfo.front,u=n-1-t.padInfo.top,l=r-1-t.padInfo.left;this.userCode="\n const ivec3 pads = ivec3("+s+", "+u+", "+l+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int d1 = coords.u;\n\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyFCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n float dotProd = 0.0;\n for (int wF = 0; wF < "+e+"; wF++) {\n float dyF = float(dyFCorner + wF) / "+o+".0;\n\n if (dyF < 0.0 || dyF >= "+t.outDepth+".0 || fract(dyF) > 0.0) {\n continue;\n }\n int idyF = int(dyF);\n\n int wFPerm = "+e+" - 1 - wF;\n\n for (int wR = 0; wR < "+n+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+a+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+n+" - 1 - wR;\n\n for (int wC = 0; wC < "+r+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+i+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+r+" - 1 - wC;\n\n for (int d2 = 0; d2 < "+t.outChannels+"; d2++) {\n float xValue = getDy(batch, idyF, idyR, idyC, d2);\n float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),Ea=function(){return function(t){this.variableNames=["x","dy"],this.outputShape=t.filterShape;var e=t.strideHeight,n=t.strideWidth,r=t.padInfo.top,o=t.padInfo.left,a=t.outChannels/t.inChannels;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int wR = coords.x;\n int wC = coords.y;\n int d1 = coords.z;\n int dm = coords.w;\n int d2 = d1 * "+a+" + dm;\n\n float dotProd = 0.0;\n\n // TO DO: Vec4 over the batch size\n for (int b = 0; b < "+t.batchSize+"; b++) {\n for (int yR = 0; yR < "+t.outHeight+"; yR++) {\n int xR = wR + yR * "+e+" - "+r+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int yC = 0; yC < "+t.outWidth+"; yC++) {\n int xC = wC + yC * "+n+" - "+o+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),Ra=function(){return function(t){this.variableNames=["dy","W"],this.outputShape=t.inShape;var e=t.filterHeight,n=t.filterWidth,r=t.strideHeight,o=t.strideWidth,a=e-1-t.padInfo.top,i=n-1-t.padInfo.left,s=t.outChannels/t.inChannels;this.userCode="\n const ivec2 pads = ivec2("+a+", "+i+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[3];\n ivec2 dyCorner = coords.yz - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n float dotProd = 0.0;\n\n for (int wR = 0; wR < "+e+"; wR++) {\n float dyR = float(dyRCorner + wR) / "+r+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = "+e+" - 1 - wR;\n\n for (int wC = 0; wC < "+n+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+o+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = "+n+" - 1 - wC;\n\n // TO DO: Vec4 over the channelMul\n for (int dm = 0; dm < "+s+"; dm++) {\n int d2 = d1 * "+s+" + dm;\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, dm);\n dotProd += xValue * wValue;\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),Ia=function(){return function(t,e,n,r){void 0===e&&(e=!1),void 0===n&&(n=null),void 0===r&&(r=!1),this.variableNames=["x","W"],this.outputShape=t.outShape;var o=t.padInfo.top,a=t.padInfo.left,i=t.strideHeight,s=t.strideWidth,u=t.dilationHeight,l=t.dilationWidth,c=t.filterHeight,h=t.filterWidth,p=4*Math.floor(t.inChannels/4),f=t.inChannels%4,d="channelsLast"===t.dataFormat,v=d?1:2,m=d?2:3,g=d?3:1,y="",x="";n&&(y=r?"float activation(float a) {\n float b = getPreluActivationWeightsAtOutCoords();\n "+n+"\n }":"\n float activation(float x) {\n "+n+"\n }\n ",x="result = activation(result);");var b=e?"result += getBiasAtOutCoords();":"";e&&this.variableNames.push("bias"),r&&this.variableNames.push("preluActivationWeights"),this.userCode="\n "+y+"\n\n const ivec2 strides = ivec2("+i+", "+s+");\n const ivec2 pads = ivec2("+o+", "+a+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d2 = coords["+g+"];\n\n ivec2 xRCCorner =\n ivec2(coords["+v+"], coords["+m+"]) * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+c+"; wR++) {\n int xR = xRCorner + wR * "+u+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+h+"; wC++) {\n int xC = xCCorner + wC * "+l+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n for (int d1 = 0; d1 < "+p+"; d1 += 4) {\n vec4 wValues = vec4(\n getW(wR, wC, d1, d2),\n getW(wR, wC, d1 + 1, d2),\n getW(wR, wC, d1 + 2, d2),\n getW(wR, wC, d1 + 3, d2)\n );\n\n if ("+d+") {\n vec4 xValues = vec4(\n getX(batch, xR, xC, d1),\n getX(batch, xR, xC, d1 + 1),\n getX(batch, xR, xC, d1 + 2),\n getX(batch, xR, xC, d1 + 3)\n );\n dotProd += dot(xValues, wValues);\n } else {\n vec4 xValues = vec4(\n getX(batch, d1, xR, xC),\n getX(batch, d1 + 1, xR, xC),\n getX(batch, d1 + 2, xR, xC),\n getX(batch, d1 + 3, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n\n if ("+(1===f)+") {\n\n if ("+d+") {\n dotProd +=\n getX(batch, xR, xC, "+p+") *\n getW(wR, wC, "+p+", d2);\n } else {\n dotProd +=\n getX(batch, "+p+", xR, xC) *\n getW(wR, wC, "+p+", d2);\n }\n\n } else if ("+(2===f)+") {\n vec2 wValues = vec2(\n getW(wR, wC, "+p+", d2),\n getW(wR, wC, "+p+" + 1, d2)\n );\n\n if ("+d+") {\n vec2 xValues = vec2(\n getX(batch, xR, xC, "+p+"),\n getX(batch, xR, xC, "+p+" + 1)\n );\n dotProd += dot(xValues, wValues);\n } else {\n vec2 xValues = vec2(\n getX(batch, "+p+", xR, xC),\n getX(batch, "+p+" + 1, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n\n } else if ("+(3===f)+") {\n vec3 wValues = vec3(\n getW(wR, wC, "+p+", d2),\n getW(wR, wC, "+p+" + 1, d2),\n getW(wR, wC, "+p+" + 2, d2)\n );\n\n if ("+d+") {\n vec3 xValues = vec3(\n getX(batch, xR, xC, "+p+"),\n getX(batch, xR, xC, "+p+" + 1),\n getX(batch, xR, xC, "+p+" + 2)\n );\n dotProd += dot(xValues, wValues);\n } else {\n vec3 xValues = vec3(\n getX(batch, "+p+", xR, xC),\n getX(batch, "+p+" + 1, xR, xC),\n getX(batch, "+p+" + 2, xR, xC)\n );\n dotProd += dot(xValues, wValues);\n }\n\n }\n }\n }\n\n float result = dotProd;\n "+b+"\n "+x+"\n setOutput(result);\n }\n "}}(),ka=function(){return function(t){this.variableNames=["x","W"],this.outputShape=t.outShape;var e=t.padInfo.front,n=t.padInfo.top,r=t.padInfo.left,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=t.dilationDepth,u=t.dilationHeight,l=t.dilationWidth,c=t.filterDepth,h=t.filterHeight,p=t.filterWidth,f=4*Math.floor(t.inChannels/4),d=t.inChannels%4;this.userCode="\n const ivec3 strides = ivec3("+o+", "+a+", "+i+");\n const ivec3 pads = ivec3("+e+", "+n+", "+r+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int d2 = coords.u;\n\n ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xFCorner = xFRCCorner.x;\n int xRCorner = xFRCCorner.y;\n int xCCorner = xFRCCorner.z;\n\n // Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get\n // y(yF, yR, yC, d2). ? = to be determined. : = across all\n // values in that axis.\n float dotProd = 0.0;\n for (int wF = 0; wF < "+c+"; wF++) {\n int xF = xFCorner + wF * "+s+";\n\n if (xF < 0 || xF >= "+t.inDepth+") {\n continue;\n }\n\n for (int wR = 0; wR < "+h+"; wR++) {\n int xR = xRCorner + wR * "+u+";\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+p+"; wC++) {\n int xC = xCCorner + wC * "+l+";\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n for (int d1 = 0; d1 < "+f+"; d1 += 4) {\n vec4 xValues = vec4(\n getX(batch, xF, xR, xC, d1),\n getX(batch, xF, xR, xC, d1 + 1),\n getX(batch, xF, xR, xC, d1 + 2),\n getX(batch, xF, xR, xC, d1 + 3)\n );\n vec4 wValues = vec4(\n getW(wF, wR, wC, d1, d2),\n getW(wF, wR, wC, d1 + 1, d2),\n getW(wF, wR, wC, d1 + 2, d2),\n getW(wF, wR, wC, d1 + 3, d2)\n );\n\n dotProd += dot(xValues, wValues);\n }\n\n if ("+(1===d)+") {\n dotProd +=\n getX(batch, xF, xR, xC, "+f+") *\n getW(wF, wR, wC, "+f+", d2);\n } else if ("+(2===d)+") {\n vec2 xValues = vec2(\n getX(batch, xF, xR, xC, "+f+"),\n getX(batch, xF, xR, xC, "+f+" + 1)\n );\n vec2 wValues = vec2(\n getW(wF, wR, wC, "+f+", d2),\n getW(wF, wR, wC, "+f+" + 1, d2)\n );\n dotProd += dot(xValues, wValues);\n } else if ("+(3===d)+") {\n vec3 xValues = vec3(\n getX(batch, xF, xR, xC, "+f+"),\n getX(batch, xF, xR, xC, "+f+" + 1),\n getX(batch, xF, xR, xC, "+f+" + 2)\n );\n vec3 wValues = vec3(\n getW(wF, wR, wC, "+f+", d2),\n getW(wF, wR, wC, "+f+" + 1, d2),\n getW(wF, wR, wC, "+f+" + 2, d2)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),Na=function(){return function(t,e,n,r){void 0===e&&(e=!1),void 0===n&&(n=null),void 0===r&&(r=!1),this.variableNames=["x","W"],this.outputShape=t.outShape;var o=t.inHeight,a=t.inWidth,i=t.padInfo.top,s=t.padInfo.left,u=t.strideHeight,l=t.strideWidth,c=t.dilationHeight,h=t.dilationWidth,p=t.filterHeight,f=t.filterWidth,d=t.outChannels/t.inChannels,v="",m="";n&&(v=r?"float activation(float a) {\n float b = getPreluActivationWeightsAtOutCoords();\n "+n+"\n }":"\n float activation(float x) {\n "+n+"\n }\n ",m="result = activation(result);");var g=e?"result += getBiasAtOutCoords();":"";e&&this.variableNames.push("bias"),r&&this.variableNames.push("preluActivationWeights"),this.userCode="\n "+v+"\n\n const ivec2 strides = ivec2("+u+", "+l+");\n const ivec2 pads = ivec2("+i+", "+s+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords.x;\n ivec2 xRCCorner = coords.yz * strides - pads;\n int d2 = coords.w;\n int d1 = d2 / "+d+";\n int q = d2 - d1 * "+d+";\n\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n // TO DO(dsmilkov): Flatten the two for loops and vec4 the operations.\n for (int wR = 0; wR < "+p+"; wR++) {\n int xR = xRCorner + wR * "+c+";\n\n if (xR < 0 || xR >= "+o+") {\n continue;\n }\n\n for (int wC = 0; wC < "+f+"; wC++) {\n int xC = xCCorner + wC * "+h+";\n\n if (xC < 0 || xC >= "+a+") {\n continue;\n }\n\n float xVal = getX(batch, xR, xC, d1);\n float wVal = getW(wR, wC, d1, q);\n dotProd += xVal * wVal;\n }\n }\n\n float result = dotProd;\n "+g+"\n "+m+"\n setOutput(result);\n }\n "}}(),Sa=function(){return function(t,e,n,r){void 0===e&&(e=!1),void 0===n&&(n=null),void 0===r&&(r=!1),this.variableNames=["x","W"],this.usesPackedTextures=!0,this.outputShape=t.outShape;for(var o=t.inHeight,a=t.inWidth,i=t.padInfo.top,s=t.padInfo.left,u=t.strideHeight,c=t.strideWidth,h=t.dilationHeight,p=t.dilationWidth,f=t.filterHeight,d=t.filterWidth,v=d,m="int xR; int xC; int xCOffset;",g=0;g= 0 && xR < "+o+" && xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+y+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+g+"C"+y+" = vec4(0.);\n }\n\n xCOffset = xC + 1 - 2;\n if(xR >= 0 && xR < "+o+" && xCOffset >= 0 && xCOffset < "+a+") {\n vec4 previous = getX(batch, xR, xCOffset, d1);\n xR"+g+"C"+y+" = vec4(previous.zw, xTexelR"+g+"C"+y+".xy);\n } else {\n xR"+g+"C"+y+" = vec4(0, 0, xTexelR"+g+"C"+y+".xy);\n }\n ":"\n if(xR >= 0 && xR < "+o+" && xC >= 0 && xC < "+a+") {\n xTexelR"+g+"C"+y+" = getX(batch, xR, xC, d1);\n } else {\n xTexelR"+g+"C"+y+" = vec4(0.);\n }\n\n xR"+g+"C"+y+" = xTexelR"+g+"C"+y+";\n ",y+1= 0 && xR < "+o+" &&\n xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+(y+2)+" = getX(batch, xR, xCOffset, d1);\n }\n ",p>1&&(m+="\n xCOffset -= 2;\n if(xR >= 0 && xR < "+o+" &&\n xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+y+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+g+"C"+y+" = vec4(0.);\n }\n "),m+="\n xR"+g+"C"+(y+1)+" = vec4(\n xTexelR"+g+"C"+y+".zw, xTexelR"+g+"C"+(y+2)+".xy);\n "):m+="\n xCOffset = xC + "+b+";\n\n if(xR >= 0 && xR < "+o+" &&\n xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+(y+2)+" = getX(batch, xR, xCOffset, d1);\n }\n\n xR"+g+"C"+(y+1)+" = xTexelR"+g+"C"+(y+2)+";\n "}}else y= 0 && xR < "+o+") {\n ",s%2==1?(m+="\n xCOffset = xC + 1 - "+c+";\n if(xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+y+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+g+"C"+y+" = vec4(0.);\n }\n\n if(xC + 1 >= 0 && xC + 1 < "+a+") {\n xTexelR"+g+"C"+(y+2)+" = getX(batch, xR, xC + 1, d1);\n } else {\n xTexelR"+g+"C"+(y+2)+" = vec4(0.);\n }\n\n xR"+g+"C"+y+" = vec4(\n xTexelR"+g+"C"+y+".zw, xTexelR"+g+"C"+(y+2)+".zw);\n ",y+1= 0 && xCOffset < "+a+") {\n final = getX(batch, xR, xCOffset, d1);\n }\n xR"+g+"C"+(y+1)+" = vec4(xTexelR"+g+"C"+(y+2)+".xy, final.xy);\n ")):(m+="\n if(xC >= 0 && xC < "+a+") {\n xTexelR"+g+"C"+y+" = getX(batch, xR, xC, d1);\n } else {\n xTexelR"+g+"C"+y+" = vec4(0.);\n }\n\n xCOffset = xC + "+c+";\n if(xCOffset >= 0 && xCOffset < "+a+") {\n xTexelR"+g+"C"+(y+2)+" = getX(batch, xR, xCOffset, d1);\n } else {\n xTexelR"+g+"C"+(y+2)+" = vec4(0.);\n }\n\n xR"+g+"C"+y+" = vec4(\n xTexelR"+g+"C"+y+".xy, xTexelR"+g+"C"+(y+2)+".xy);\n ",y+11?[""+(i-1)/(c-1),"(y2-y1) * height_ratio","y1*"+d+" + float(y)*(height_scale)"]:["0.0","0.0","0.5 * (y1+y2) * "+d],g=m[0],y=m[1],x=m[2],b=h>1?[""+(s-1)/(h-1),"(x2-x1) * width_ratio","x1*"+v+" + float(x)*(width_scale)"]:["0.0","0.0","0.5 * (x1+x2) * "+v],w=b[0],C=b[1],E=b[2];this.userCode="\n const float height_ratio = float("+g+");\n const float width_ratio = float("+w+");\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int y = coords[1];\n int x = coords[2];\n int d = coords[3];\n\n // get box vals\n float y1 = getBoxes(b,0);\n float x1 = getBoxes(b,1);\n float y2 = getBoxes(b,2);\n float x2 = getBoxes(b,3);\n\n // get image in batch index\n int bInd = round(getBoxInd(b));\n if(bInd < 0 || bInd >= "+a+") {\n return;\n }\n\n float height_scale = "+y+";\n float width_scale = "+C+";\n\n float in_y = "+x+";\n if( in_y < 0.0 || in_y > "+d+" ) {\n setOutput(float("+o+"));\n return;\n }\n float in_x = "+E+";\n if( in_x < 0.0 || in_x > "+v+" ) {\n setOutput(float("+o+"));\n return;\n }\n\n vec2 sourceFracIndexCR = vec2(in_x,in_y);\n if("+p+" == 1) {\n // Compute the four integer indices.\n ivec2 sourceFloorCR = ivec2(sourceFracIndexCR);\n ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR));\n\n float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d);\n float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d);\n float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d);\n float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d);\n\n vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR);\n\n float top = topLeft + (topRight - topLeft) * fracCR.x;\n float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x;\n float newValue = top + (bottom - top) * fracCR.y;\n setOutput(newValue);\n } else {\n // Compute the coordinators of nearest neighbor point.\n ivec2 sourceNearestCR = ivec2(floor(\n sourceFracIndexCR + vec2(0.5,0.5)));\n float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d);\n setOutput(newValue);\n }\n }\n "}}(),Ta=function(){return function(t,e,n){this.variableNames=["x"],this.outputShape=t;var r=t.length,o=t[t.length-1],a=n?"<":">";this.userCode="\n int getIndex(int i) {\n "+(n?"return "+o+" -i - 1;":"return i;")+"\n }\n\n void main() {\n "+Xo(r)+" coords = getOutputCoords();\n int end = "+Da(r,"coords")+";\n float val = 0.0;\n for (int i = "+o+" - 1; i >= 0; i -= 1) {\n int idx = getIndex(i);\n if (idx "+a+" end) {\n continue;\n }\n if (idx == end && "+e+") {\n continue;\n }\n "+Da(r,"coords")+" = idx;\n val += getX("+function(t,e){if(1===t)return""+e;if(2===t)return e+".x, "+e+".y";if(3===t)return e+".x, "+e+".y, "+e+".z";if(4===t)return e+".x, "+e+".y, "+e+".z, "+e+".w";throw Error("Cumulative sum for rank "+t+" is not yet supported")}(r,"coords")+");\n }\n setOutput(val);\n }\n "}}();function Da(t,e){if(1===t)return""+e;if(2===t)return e+".y";if(3===t)return e+".z";if(4===t)return e+".w";throw Error("Cumulative sum for rank "+t+" is not yet supported")}var _a=function(){return function(t,e){this.variableNames=["A"];var n=Bo();this.outputShape=t,this.userCode="\n ivec3 outCoordsFromFlatIndex(int index) {\n "+Po(["r","c","d"],t)+"\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+e[0]+", "+e[1]+"));\n int index = 4 * (resTexRC.x * "+e[1]+" + resTexRC.y);\n\n vec4 result = vec4(0.);\n\n for (int i=0; i<4; i++) {\n int flatIndex = index + i;\n ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n result[i] = getA(rc.x, rc.y, rc.z);\n }\n\n "+n.output+" = result;\n }\n "}}(),Oa=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0;var n=Bo();this.outputShape=t,this.userCode="\n ivec3 outCoordsFromFlatIndex(int index) {\n "+Po(["r","c","d"],t)+"\n return ivec3(r, c, d);\n }\n\n void main() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2("+e[0]+", "+e[1]+"));\n int index = 4 * (resTexRC.x * "+e[1]+" + resTexRC.y);\n\n vec4 result = vec4(0.);\n\n for (int i=0; i<4; i++) {\n int flatIndex = index + i;\n ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z));\n }\n\n "+n.output+" = result;\n }\n "}}(),Fa=function(){function t(t,e,n){this.variableNames=["x"],this.outputShape=[],this.outputShape=t,this.blockSize=e,this.dataFormat=n,this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int h = "+this.getHeightCoordString()+";\n int w = "+this.getWidthCoordString()+";\n int d = "+this.getDepthCoordString()+";\n\n int in_h = h / "+e+";\n int offset_h = imod(h, "+e+");\n int in_w = w / "+e+";\n int offset_w = imod(w, "+e+");\n int offset_d = (offset_h * "+e+" + offset_w) *\n "+this.getOutputDepthSize()+";\n int in_d = d + offset_d;\n\n float result = "+this.getInputSamplingString()+";\n setOutput(result);\n }\n "}return t.prototype.getHeightCoordString=function(){return"NHWC"===this.dataFormat?"coords[1]":"coords[2]"},t.prototype.getWidthCoordString=function(){return"NHWC"===this.dataFormat?"coords[2]":"coords[3]"},t.prototype.getDepthCoordString=function(){return"NHWC"===this.dataFormat?"coords[3]":"coords[1]"},t.prototype.getOutputDepthSize=function(){return"NHWC"===this.dataFormat?this.outputShape[3]:this.outputShape[1]},t.prototype.getInputSamplingString=function(){return"NHWC"===this.dataFormat?"getX(b, in_h, in_w, in_d)":"getX(b, in_d, in_h, in_w)"},t}(),Ma=function(){return function(t){this.variableNames=["X"],this.outputShape=[t,t],this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0;\n setOutput(val);\n }\n "}}(),Ba=function(){return function(t){this.variableNames=["A"];var e=Bo();this.outputShape=t,this.userCode="\n "+Wo+"\n\n void main() {\n float x = getAAtOutCoords();\n "+e.output+" = encode_float(x);\n }\n "}}(),Pa=function(){return function(t){this.variableNames=["A"],this.usesPackedTextures=!0;var e=Bo();this.outputShape=t,this.userCode="\n "+Wo+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));\n "+e.output+" = encode_float(x);\n }\n "}}(),La=function(){return function(t,e,n){void 0===n&&(n=!1),this.variableNames=["A"];var r=Bo(),o=e[0],a=e[1];this.outputShape=t;var i="result";n&&(i="floor(result * 255. + 0.5)"),this.userCode="\n "+Lo(t)+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n\n int flatIndex = getFlatIndex(coords);\n int offset = imod(flatIndex, 4);\n\n flatIndex = idiv(flatIndex, 4, 1.);\n \n int r = flatIndex / "+a+";\n int c = imod(flatIndex, "+a+");\n vec2 uv = (vec2(c, r) + halfCR) / vec2("+a+".0, "+o+".0);\n vec4 values = "+r.texture2D+"(A, uv);\n\n float result;\n\n if(offset == 0) {\n result = values[0];\n } else if(offset == 1) {\n result = values[1];\n } else if(offset == 2) {\n result = values[2];\n } else {\n result = values[3];\n }\n\n "+r.output+" = vec4("+i+", 0., 0., 0.);\n }\n "}}(),Wa=function(){return function(t,e,n){void 0===n&&(n=!1),this.variableNames=["A"];var r=Bo(),o=e[0],a=e[1];this.outputShape=t;var i="",s="result";n&&(s="floor(result * 255. + 0.5)");for(var u=0;u<=1;u++)for(var l=0;l<=1;l++){var c=2*u+l;i+="\n localCoords = coords;\n if(localCoords[2] + "+l+" < "+t[2]+") {\n localCoords[2] += "+l+";\n if(localCoords[1] + "+u+" < "+t[1]+") {\n localCoords[1] += "+u+";\n\n flatIndex = getFlatIndex(localCoords);\n offset = imod(flatIndex, 4);\n \n flatIndex = idiv(flatIndex, 4, 1.);\n\n r = flatIndex / "+a+";\n c = imod(flatIndex, "+a+");\n uv = (vec2(c, r) + halfCR) / vec2("+a+".0, "+o+".0);\n values = "+r.texture2D+"(A, uv);\n\n if(offset == 0) {\n result["+c+"] = values[0];\n } else if(offset == 1) {\n result["+c+"] = values[1];\n } else if(offset == 2) {\n result["+c+"] = values[2];\n } else {\n result["+c+"] = values[3];\n }\n }\n }\n "}this.userCode="\n "+Lo(t)+"\n\n void main() {\n ivec3 coords = getOutputCoords();\n\n vec4 result = vec4(0.);\n int flatIndex, r, c, offset;\n ivec3 localCoords;\n vec2 uv;\n vec4 values;\n \n "+i+"\n\n "+r.output+" = "+s+";\n }\n "}}(),Ua="return real * expR - imag * expI;",Va="return real * expI + imag * expR;",za=function(){return function(t,e,n){this.variableNames=["real","imag"];var r=e[1];this.outputShape=e;var o=n?"2.0 * "+Math.PI:"-2.0 * "+Math.PI,a=n?r+".0":"1.0";this.userCode="\n const float exponentMultiplier = "+o+";\n\n float unaryOpComplex(float real, float expR, float imag, float expI) {\n "+t+"\n }\n\n float mulMatDFT(int batch, int index) {\n float indexRatio = float(index) / float("+r+");\n float exponentMultiplierTimesIndexRatio =\n exponentMultiplier * indexRatio;\n\n float result = 0.0;\n\n for (int i = 0; i < "+r+"; i++) {\n // x = (-2|2 * PI / N) * index * i;\n float x = exponentMultiplierTimesIndexRatio * float(i);\n float expR = cos(x);\n float expI = sin(x);\n float real = getReal(batch, i);\n float imag = getImag(batch, i);\n\n result +=\n unaryOpComplex(real, expR, imag, expI) / "+a+";\n }\n\n return result;\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n setOutput(mulMatDFT(coords[0], coords[1]));\n }\n "}}(),Ga=function(){function t(t,e){this.outputShape=[],this.variableNames=["x"],this.outputShape=t,this.userCode="\n uniform float value;\n void main() {\n // Input can be obtained from uniform value.\n setOutput(value);\n }\n "}return t.prototype.getCustomSetupFunc=function(t){var e=this;return function(n,r){null==e.valueLoc&&(e.valueLoc=n.getUniformLocationNoThrow(r,"value")),n.gl.uniform1f(e.valueLoc,t)}},t}(),Ha=function(){return function(t){this.variableNames=["A"];var e=Bo(),n=t[0],r=t[1];this.outputShape=t,this.userCode="\n void main() {\n ivec3 coords = getOutputCoords();\n int texR = coords[0];\n int texC = coords[1];\n int depth = coords[2];\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2("+r+".0, "+n+".0);\n\n vec4 values = "+e.texture2D+"(A, uv);\n float value;\n if (depth == 0) {\n value = values.r;\n } else if (depth == 1) {\n value = values.g;\n } else if (depth == 2) {\n value = values.b;\n } else if (depth == 3) {\n value = values.a;\n }\n\n setOutput(floor(value * 255.0 + 0.5));\n }\n "}}(),qa=function(){return function(t){this.variableNames=["A"];var e=Bo(),n=t[0],r=t[1];this.outputShape=t,this.userCode="\n void main() {\n ivec3 coords = getOutputCoords();\n int texR = coords[0];\n int texC = coords[1];\n int depth = coords[2];\n\n vec4 result = vec4(0.);\n\n for(int row=0; row<=1; row++) {\n for(int col=0; col<=1; col++) {\n texC = coords[1] + row;\n depth = coords[2] + col;\n\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2("+r+".0, "+n+".0);\n vec4 values = "+e.texture2D+"(A, uv);\n float value;\n if (depth == 0) {\n value = values.r;\n } else if (depth == 1) {\n value = values.g;\n } else if (depth == 2) {\n value = values.b;\n } else if (depth == 3) {\n value = values.a;\n }\n\n result[row * 2 + col] = floor(value * 255.0 + 0.5);\n }\n }\n\n "+e.output+" = result;\n }\n "}}(),$a=function(){return function(t,e,n){this.variableNames=["A","indices"];var r=t.slice();r[n]=e,this.outputShape=r,this.rank=r.length;var o=Xo(this.rank),a=function(t,e){var n=t.length;if(n>4)throw Error("Gather for rank "+n+" is not yet supported");if(1===n)return"int(getIndices(resRC))";for(var r=["resRC.x","resRC.y","resRC.z","resRC.w"],o=[],a=0;a1?"strides[j]":"strides";this.userCode="\n "+r+" strides = "+r+"("+this.strides+");\n void main() {\n "+o+" coords = getOutputCoords();\n int flattenIndex = 0;\n for (int j = 0; j < "+this.sliceDim+"; j++) {\n int index = round(getIndices(coords[0], j));\n flattenIndex += index * "+a+";\n }\n setOutput(getX(flattenIndex, coords[1]));\n }\n "}}();function ja(t,e){var n=Bo();return $t(t,e,n.version+"\n precision highp float;\n "+n.attribute+" vec3 clipSpacePos;\n "+n.attribute+" vec2 uv;\n "+n.varyingVs+" vec2 resultUV;\n\n void main() {\n gl_Position = vec4(clipSpacePos, 1);\n resultUV = uv;\n }")}function Xa(t,e){return te(t,e,new Float32Array([-1,1,0,0,1,-1,-1,0,0,0,1,1,0,1,1,1,-1,0,1,0]))}function Ya(t,e){return ee(t,e,new Uint16Array([0,1,2,2,1,3]))}function Qa(t,e,n,r,o,a,i){re(n,r);var s=ne(t,e),u=t.TEXTURE_2D;return Ut(t,e,function(){return t.bindTexture(u,s)}),Ut(t,e,function(){return t.texParameteri(u,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE)}),Ut(t,e,function(){return t.texParameteri(u,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE)}),Ut(t,e,function(){return t.texParameteri(u,t.TEXTURE_MIN_FILTER,t.NEAREST)}),Ut(t,e,function(){return t.texParameteri(u,t.TEXTURE_MAG_FILTER,t.NEAREST)}),Ut(t,e,function(){return t.texImage2D(u,0,o,n,r,0,a,i,null)}),Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)}),s}function Ja(t,e,n,r,o){var a=Bt(n,r);return Qa(t,e,a[0],a[1],o.internalFormatFloat,o.textureFormatFloat,t.FLOAT)}function Za(t,e,n,r,o){var a=Bt(n,r);return Qa(t,e,a[0],a[1],o.internalFormatHalfFloat,o.textureFormatFloat,o.textureTypeHalfFloat)}function ti(t,e,n,r,o){var a=Bt(n,r);return Qa(t,e,a[0],a[1],t.RGBA,t.RGBA,t.UNSIGNED_BYTE)}function ei(t,e,n,r,o){var a=Lt(n,r);return Qa(t,e,a[0],a[1],o.internalFormatPackedFloat,t.RGBA,t.FLOAT)}function ni(t,e,n,r,o){var a=Lt(n,r);return Qa(t,e,a[0],a[1],o.internalFormatPackedHalfFloat,t.RGBA,o.textureTypeHalfFloat)}function ri(t,e,n,r){return Ut(t,e,function(){return t.bindBuffer(t.ARRAY_BUFFER,r)}),ae(t,e,n,"clipSpacePos",r,3,20,0)&&ae(t,e,n,"uv",r,2,20,12)}function oi(t,e,n,r,o,a,i){var s,u,l;Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)}),a instanceof Uint8Array?(s=new Uint8Array(r*o*4),u=t.UNSIGNED_BYTE,l=t.RGBA):(s=new Float32Array(r*o*4),u=t.FLOAT,l=i.internalFormatPackedFloat),s.set(a),Ut(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,l,r,o,0,t.RGBA,u,s)}),Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)})}function ai(t,e,n,r){Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,n)}),r.data instanceof Uint8Array?Ut(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,t.RGBA,r.width,r.height,0,t.RGBA,t.UNSIGNED_BYTE,r.data)}):Ut(t,e,function(){return t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,r)}),Ut(t,e,function(){return t.bindTexture(t.TEXTURE_2D,null)})}function ii(t,e,n,r,o){var a=t.createBuffer();Ut(t,e,function(){return t.bindBuffer(t.PIXEL_PACK_BUFFER,a)});var i=16*n*r;return Ut(t,e,function(){return t.bufferData(t.PIXEL_PACK_BUFFER,i,t.STREAM_READ)}),Ut(t,e,function(){return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,0)}),Ut(t,e,function(){return t.bindBuffer(t.PIXEL_PACK_BUFFER,null)}),a}function si(t,e,n){var r=t,o=new Float32Array(n);return r.bindBuffer(r.PIXEL_PACK_BUFFER,e),r.getBufferSubData(r.PIXEL_PACK_BUFFER,0,o),r.bindBuffer(r.PIXEL_PACK_BUFFER,null),o}function ui(t,e,n,r,o){var a=Bt(n,r),i=a[0],s=a[1],u=new Uint8Array(n*r*4);return Ut(t,e,function(){return t.readPixels(0,0,i,s,o.downloadTextureFormat,t.UNSIGNED_BYTE,u)}),new Float32Array(u.buffer)}function li(t,e,n,r,o,a,i,s){var u=t,l=new Float32Array(function(t,e){var n=Lt(t,e);return n[0]*n[1]*4}(a,i));return u.bindBuffer(u.PIXEL_PACK_BUFFER,e),u.getBufferSubData(u.PIXEL_PACK_BUFFER,0,l),u.bindBuffer(u.PIXEL_PACK_BUFFER,null),l}function ci(t,e,n,r){var o=new Float32Array(n*r*4);return Ut(t,e,function(){return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,o)}),o}var hi=Object.freeze({createVertexShader:ja,createVertexBuffer:Xa,createIndexBuffer:Ya,createFloat32MatrixTexture:Ja,createFloat16MatrixTexture:Za,createUnsignedBytesMatrixTexture:ti,createPackedMatrixTexture:ei,createFloat16PackedMatrixTexture:ni,bindVertexProgramAttributeStreams:ri,uploadDenseMatrixToTexture:oi,uploadPixelDataToTexture:ai,createBufferFromOutputTexture:ii,downloadFloat32MatrixFromBuffer:si,downloadByteEncodedFloatMatrixFromOutputTexture:ui,downloadPackedMatrixFromBuffer:li,downloadMatrixFromPackedOutputTexture:ci}),pi=function(){function t(t){this.outputTexture=null,this.program=null,this.disposed=!1,this.vertexAttrsAreBound=!1,this.itemsToPoll=[];var e=a().getNumber("WEBGL_VERSION");if(null!=t?(this.gl=t,Ot(e,t)):this.gl=Ft(e),1===a().getNumber("WEBGL_VERSION"))this.textureFloatExtension=qt(this.gl,this.debug,"OES_texture_float"),this.colorBufferFloatExtension=this.gl.getExtension("WEBGL_color_buffer_float"),this.textureHalfFloatExtension=qt(this.gl,this.debug,"OES_texture_half_float"),this.colorBufferHalfFloatExtension=this.gl.getExtension("EXT_color_buffer_half_float");else{if(Ie(this.gl,"EXT_color_buffer_float"))this.colorBufferFloatExtension=this.gl.getExtension("EXT_color_buffer_float");else{if(!Ie(this.gl,"EXT_color_buffer_half_float"))throw new Error("GL context does not support color renderable floats");this.colorBufferHalfFloatExtension=this.gl.getExtension("EXT_color_buffer_half_float")}}this.vertexBuffer=Xa(this.gl,this.debug),this.indexBuffer=Ya(this.gl,this.debug),this.framebuffer=oe(this.gl,this.debug),this.textureConfig=Wt(this.gl,this.textureHalfFloatExtension)}return Object.defineProperty(t.prototype,"debug",{get:function(){return a().getBool("DEBUG")},enumerable:!0,configurable:!0}),t.prototype.dispose=function(){var t=this;if(!this.disposed){null!=this.program&&console.warn("Disposing a GPGPUContext that still has a bound WebGLProgram. This is probably a resource leak, delete the program with GPGPUContext.deleteProgram before disposing."),null!=this.outputTexture&&console.warn("Disposing a GPGPUContext that still has a bound output matrix texture. This is probably a resource leak, delete the output matrix texture with GPGPUContext.deleteMatrixTexture before disposing.");var e=this.gl;Ut(e,this.debug,function(){return e.finish()}),Ut(e,this.debug,function(){return e.bindFramebuffer(e.FRAMEBUFFER,null)}),Ut(e,this.debug,function(){return e.deleteFramebuffer(t.framebuffer)}),Ut(e,this.debug,function(){return e.bindBuffer(e.ARRAY_BUFFER,null)}),Ut(e,this.debug,function(){return e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null)}),Ut(e,this.debug,function(){return e.deleteBuffer(t.indexBuffer)}),this.disposed=!0}},t.prototype.createFloat32MatrixTexture=function(t,e){return this.throwIfDisposed(),Ja(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createFloat16MatrixTexture=function(t,e){return this.throwIfDisposed(),Za(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createUnsignedBytesMatrixTexture=function(t,e){return this.throwIfDisposed(),ti(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.uploadPixelDataToTexture=function(t,e){this.throwIfDisposed(),ai(this.gl,this.debug,t,e)},t.prototype.uploadDenseMatrixToTexture=function(t,e,n,r){this.throwIfDisposed(),oi(this.gl,this.debug,t,e,n,r,this.textureConfig)},t.prototype.createFloat16PackedMatrixTexture=function(t,e){return this.throwIfDisposed(),ni(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.createPackedMatrixTexture=function(t,e){return this.throwIfDisposed(),ei(this.gl,this.debug,t,e,this.textureConfig)},t.prototype.deleteMatrixTexture=function(t){var e=this;this.throwIfDisposed(),this.outputTexture===t&&(he(this.gl,this.debug,this.framebuffer),this.outputTexture=null),Ut(this.gl,this.debug,function(){return e.gl.deleteTexture(t)})},t.prototype.downloadByteEncodedFloatMatrixFromOutputTexture=function(t,e,n){var r=this;return this.downloadMatrixDriver(t,function(){return ui(r.gl,r.debug,e,n,r.textureConfig)})},t.prototype.downloadPackedMatrixFromBuffer=function(t,e,n,r,o,a){return li(this.gl,t,0,0,0,o,a,this.textureConfig)},t.prototype.downloadFloat32MatrixFromBuffer=function(t,e){return si(this.gl,t,e)},t.prototype.createBufferFromTexture=function(t,e,n){this.bindTextureToFrameBuffer(t);var r=ii(this.gl,this.debug,e,n,this.textureConfig);return this.unbindTextureToFrameBuffer(),r},t.prototype.createAndWaitForFence=function(){var t=this.createFence(this.gl);return this.pollFence(t)},t.prototype.createFence=function(t){var e,n,r=this;if(a().getBool("WEBGL_FENCE_API_ENABLED")){var o=t,i=o.fenceSync(o.SYNC_GPU_COMMANDS_COMPLETE,0);t.flush(),n=function(){var t=o.clientWaitSync(i,0,0);return t===o.ALREADY_SIGNALED||t===o.CONDITION_SATISFIED},e=i}else a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(e=this.beginQuery(),this.endQuery(),n=function(){return r.isQueryAvailable(e,a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))}):n=function(){return!0};return{query:e,isFencePassed:n}},t.prototype.downloadMatrixFromPackedTexture=function(t,e,n){var r=this;return this.downloadMatrixDriver(t,function(){return ci(r.gl,r.debug,e,n)})},t.prototype.createProgram=function(t){this.throwIfDisposed();var e=this.gl,n=Kt(e,this.debug,t),r=ja(e,this.debug),o=Qt(e,this.debug);return Ut(e,this.debug,function(){return e.attachShader(o,r)}),Ut(e,this.debug,function(){return e.attachShader(o,n)}),Jt(e,this.debug,o),this.debug&&Zt(e,this.debug,o),this.vertexAttrsAreBound||(this.setProgram(o),this.vertexAttrsAreBound=ri(e,this.debug,this.program,this.vertexBuffer)),o},t.prototype.deleteProgram=function(t){var e=this;this.throwIfDisposed(),t===this.program&&(this.program=null),null!=t&&Ut(this.gl,this.debug,function(){return e.gl.deleteProgram(t)})},t.prototype.setProgram=function(t){var e=this;this.throwIfDisposed(),this.program=t,null!=this.program&&this.debug&&Zt(this.gl,this.debug,this.program),Ut(this.gl,this.debug,function(){return e.gl.useProgram(t)})},t.prototype.getUniformLocation=function(t,e,n){return void 0===n&&(n=!0),this.throwIfDisposed(),n?se(this.gl,this.debug,t,e):ue(this.gl,t,e)},t.prototype.getAttributeLocation=function(t,e){var n=this;return this.throwIfDisposed(),Ut(this.gl,this.debug,function(){return n.gl.getAttribLocation(t,e)})},t.prototype.getUniformLocationNoThrow=function(t,e){return this.throwIfDisposed(),this.gl.getUniformLocation(t,e)},t.prototype.setInputMatrixTexture=function(t,e,n){this.throwIfDisposed(),this.throwIfNoProgram(),le(this.gl,this.debug,this.program,t,e,n)},t.prototype.setOutputMatrixTexture=function(t,e,n){this.setOutputMatrixTextureDriver(t,n,e)},t.prototype.setOutputPackedMatrixTexture=function(t,e,n){this.throwIfDisposed();var r=Lt(e,n),o=r[0],a=r[1];this.setOutputMatrixTextureDriver(t,o,a)},t.prototype.setOutputMatrixWriteRegion=function(t,e,n,r){this.setOutputMatrixWriteRegionDriver(n,t,r,e)},t.prototype.setOutputPackedMatrixWriteRegion=function(t,e,n,r){throw new Error("setOutputPackedMatrixWriteRegion not implemented.")},t.prototype.debugValidate=function(){null!=this.program&&Zt(this.gl,this.debug,this.program),pe(this.gl)},t.prototype.executeProgram=function(){this.throwIfDisposed(),this.throwIfNoProgram();var t=this.gl;this.debug&&this.debugValidate(),Ut(t,this.debug,function(){return t.drawElements(t.TRIANGLES,6,t.UNSIGNED_SHORT,0)})},t.prototype.blockUntilAllProgramsCompleted=function(){var t=this;this.throwIfDisposed(),Ut(this.gl,this.debug,function(){return t.gl.finish()})},t.prototype.getQueryTimerExtension=function(){return null==this.disjointQueryTimerExtension&&(this.disjointQueryTimerExtension=qt(this.gl,this.debug,2===a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")?"EXT_disjoint_timer_query_webgl2":"EXT_disjoint_timer_query")),this.disjointQueryTimerExtension},t.prototype.getQueryTimerExtensionWebGL2=function(){return this.getQueryTimerExtension()},t.prototype.getQueryTimerExtensionWebGL1=function(){return this.getQueryTimerExtension()},t.prototype.beginQuery=function(){if(2===a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){var t=this.gl,e=this.getQueryTimerExtensionWebGL2(),n=t.createQuery();return t.beginQuery(e.TIME_ELAPSED_EXT,n),n}var r=this.getQueryTimerExtensionWebGL1(),o=r.createQueryEXT();return r.beginQueryEXT(r.TIME_ELAPSED_EXT,o),o},t.prototype.endQuery=function(){if(2!==a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){var t=this.getQueryTimerExtensionWebGL1();t.endQueryEXT(t.TIME_ELAPSED_EXT)}else{var e=this.gl,n=this.getQueryTimerExtensionWebGL2();e.endQuery(n.TIME_ELAPSED_EXT)}},t.prototype.waitForQueryAndGetTime=function(t){return n(this,void 0,void 0,function(){var e=this;return r(this,function(n){switch(n.label){case 0:return[4,w(function(){return e.disposed||e.isQueryAvailable(t,a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))})];case 1:return n.sent(),[2,this.getQueryTime(t,a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))]}})})},t.prototype.getQueryTime=function(t,e){if(0===e)return null;if(2===e){var n=this.gl;return n.getQueryParameter(t,n.QUERY_RESULT)/1e6}var r=this.getQueryTimerExtensionWebGL1();return r.getQueryObjectEXT(t,r.QUERY_RESULT_EXT)/1e6},t.prototype.isQueryAvailable=function(t,e){if(0===e)return!0;if(2===e){var n=this.gl,r=this.getQueryTimerExtensionWebGL2(),o=n.getQueryParameter(t,n.QUERY_RESULT_AVAILABLE);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(r.GPU_DISJOINT_EXT)),o&&!this.disjoint}o=(r=this.getQueryTimerExtensionWebGL1()).getQueryObjectEXT(t,r.QUERY_RESULT_AVAILABLE_EXT);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(r.GPU_DISJOINT_EXT)),o&&!this.disjoint},t.prototype.pollFence=function(t){var e=this;return new Promise(function(n){e.addItemToPoll(function(){return t.isFencePassed()},function(){return n()})})},t.prototype.pollItems=function(){for(var t=function(t){for(var e=0;e1||w(function(){return n.pollItems(),0===n.itemsToPoll.length})},t.prototype.bindTextureToFrameBuffer=function(t){this.throwIfDisposed(),ce(this.gl,this.debug,t,this.framebuffer),this.debug&&pe(this.gl)},t.prototype.unbindTextureToFrameBuffer=function(){null!=this.outputTexture?(ce(this.gl,this.debug,this.outputTexture,this.framebuffer),this.debug&&pe(this.gl)):he(this.gl,this.debug,this.framebuffer)},t.prototype.downloadMatrixDriver=function(t,e){this.bindTextureToFrameBuffer(t);var n=e();return this.unbindTextureToFrameBuffer(),n},t.prototype.setOutputMatrixTextureDriver=function(t,e,n){this.throwIfDisposed();var r=this.gl;ce(r,this.debug,t,this.framebuffer),this.debug&&pe(r),this.outputTexture=t,Ut(r,this.debug,function(){return r.viewport(0,0,e,n)}),Ut(r,this.debug,function(){return r.scissor(0,0,e,n)})},t.prototype.setOutputMatrixWriteRegionDriver=function(t,e,n,r){var o=this;this.throwIfDisposed(),Ut(this.gl,this.debug,function(){return o.gl.scissor(t,e,n,r)})},t.prototype.throwIfDisposed=function(){if(this.disposed)throw new Error("Attempted to use disposed GPGPUContext.")},t.prototype.throwIfNoProgram=function(){if(null==this.program)throw new Error("No GPU program is currently set.")},t}();function fi(t,e){if(t.length!==e.length)throw Error("Binary was compiled with "+t.length+" inputs, but was executed with "+e.length+" inputs");t.forEach(function(t,n){var r=t.logicalShape,o=e[n],a=o.shape;if(!m(r,a))throw Error("Binary was compiled with different shapes than the current args. Shapes "+r+" and "+a+" must match");if(!t.isUniform||!o.isUniform){var i=t.texShape,s=o.isUniform?null:o.texData.texShape;if(!m(i,s))throw Error("Binary was compiled with different texture shapes than the current args. Shape "+i+" and "+s+" must match")}})}var di=function(){return function(t,e,n){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;for(var r=n.filterWidth,o=n.inChannels,a=n.strideWidth,i=n.strideHeight,s=n.padInfo,u=n.outWidth,l=n.dilationWidth,c=n.dilationHeight,h=n.dataFormat,p=s.left,f=s.top,d=o*r,v=Bo(),m="channelsLast"===h,g=m?0:1,y=m?1:2,x="",b=0;b<=1;b++)for(var w=0;w<=1;w++)x+="\n blockIndex = rc.y + "+w+";\n pos = rc.x + "+b+";\n\n if(blockIndex < "+t[1]+" && pos < "+t[0]+") {\n offsetY = int(blockIndex / ("+u+")) * "+i+" - "+f+";\n d0 = offsetY + "+c+" * (pos / "+d+");\n\n if(d0 < "+e[g]+" && d0 >= 0) {\n\n offsetX = int(mod(float(blockIndex), "+u+".) * "+a+". - "+p+".);\n d1 = offsetX + "+l+" * (int(mod(float(pos), "+d+".) / "+o+".));\n\n if(d1 < "+e[y]+" && d1 >= 0) {\n\n ch = int(mod(float(pos), "+o+".));\n\n if ("+m+") {\n innerDims = vec2(d1, ch);\n result["+(2*b+w)+"] = getChannel(\n getA(d0, int(innerDims.x),\n int(innerDims.y)), innerDims);\n } else {\n innerDims = vec2(d0, d1);\n result["+(2*b+w)+"] = getChannel(\n getA(ch, int(innerDims.x),\n int(innerDims.y)), innerDims);\n }\n }\n }\n }\n ";this.userCode="\n void main() {\n ivec2 rc = getOutputCoords();\n\n vec4 result = vec4(0);\n\n int blockIndex, pos, offsetY, d0, offsetX, d1, ch;\n vec2 innerDims;\n\n "+x+"\n\n "+v.output+" = result;\n }\n "}}(),vi=function(){return function(t,e,n,r,o){this.variableNames=["x"],this.outputShape=[];var a,i=e,s=t[3]-1;this.outputShape=t;var u="float("+n+") + float("+r+") * sum";a=.5===o?"inversesqrt("+u+")":1===o?"1.0/("+u+")":"exp(log("+u+") * float(-"+o+"));",this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int r = coords[1];\n int c = coords[2];\n int d = coords[3];\n float x = getX(b, r, c, d);\n float sum = 0.0;\n for (int j = -"+i+"; j <= "+i+"; j++) {\n int idx = d + j;\n if (idx >= 0 && idx <= "+s+") {\n float z = getX(b, r, c, idx);\n sum += z * z;\n }\n }\n float val = x * "+a+";\n setOutput(val);\n }\n "}}(),mi=function(){return function(t,e,n,r,o){this.variableNames=["inputImage","outputImage","dy"],this.outputShape=[],this.outputShape=t,this.depth=t[3],this.depthRadius=e,this.bias=n,this.alpha=r,this.beta=o,this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int r = coords[1];\n int c = coords[2];\n\n float result = 0.0;\n for (int d = 0; d < "+this.depth+"; ++d) {\n int depthBegin = int(max(0.0, float(d - "+e+")));\n int depthEnd = int(min(float("+this.depth+"),\n float(d + "+e+" + 1)));\n\n const int MIN_DEPTH_BEGIN = 0;\n const int MAX_DEPTH_END = "+this.depth+";\n\n float norm = 0.0;\n for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) {\n if (k < depthBegin){\n continue;\n }\n else if (k >= depthBegin && k < depthEnd) {\n norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k);\n }\n else {\n break;\n }\n }\n\n norm = float("+r+") * norm + float("+n+");\n\n for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){\n if (k < depthBegin){\n continue;\n }\n else if (k >= depthBegin && k < depthEnd){\n float dyi = -2.0 * float("+r+")\n * float("+o+")\n * getInputImage(b ,r ,c, k) * getOutputImage(b, r, c, d)\n / norm;\n if (k == d) {\n dyi += pow(norm, -1.0 * "+o+");\n }\n if (k == coords[3]) {\n dyi *= getDy(b, r, c, d);\n result += dyi;\n }\n }\n else {\n break;\n }\n }\n }\n setOutput(result);\n }\n "}}(),gi=function(){return function(t,e,n,r,o){this.variableNames=["x"],this.outputShape=[],this.usesPackedTextures=!0;var a,i=e,s=t[3]-1;this.outputShape=t;var u="float("+n+") + float("+r+") * sum";a=.5===o?"inversesqrt("+u+")":1===o?"1.0/("+u+")":"exp(log("+u+") * float(-"+o+"));",this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords.x;\n int r = coords.y;\n int c = coords.z;\n int d = coords.w;\n\n bool hasNextCol = d < "+this.outputShape[3]+";\n bool hasNextRow = c < "+this.outputShape[2]+";\n\n vec4 sum = vec4(0.);\n vec4 xFragAtOutputCoords = getX(b, r, c, d);\n\n vec4 xAtOutputCoords = vec4(\n getChannel(xFragAtOutputCoords, vec2(c, d)),\n hasNextCol ?\n getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0,\n hasNextRow ?\n getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0,\n (hasNextRow && hasNextCol) ?\n getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0\n );\n\n int firstChannel = d - "+i+";\n vec2 cache = vec2(0.);\n if(firstChannel >= 0){\n vec4 firstChannelFrag = getX(b, r, c, firstChannel);\n cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel));\n if(hasNextRow){\n cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel));\n }\n }\n\n ivec2 depth = ivec2(d, d + 1);\n for (int j = - "+i+"; j <= "+i+"; j++) {\n ivec2 idx = depth + j;\n bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0));\n bvec2 belowUpperBound = lessThanEqual(idx, ivec2("+s+"));\n\n bool depthInRange = aboveLowerBound.x && belowUpperBound.x;\n bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y;\n\n if(depthInRange || depthPlusOneInRange){\n vec4 z = vec4(0.);\n vec4 xFragAtCurrentDepth;\n z.xz = cache.xy;\n if(depthPlusOneInRange && hasNextCol){\n xFragAtCurrentDepth = idx.y != d ?\n getX(b, r, c, idx.y) : xFragAtOutputCoords;\n z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y));\n if(hasNextRow){\n z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y));\n }\n }\n cache.xy = z.yw;\n sum += z * z;\n }\n }\n vec4 result = xAtOutputCoords * "+a+";\n setOutput(result);\n }\n "}}(),yi=function(){return function(t){this.variableNames=["dy","maxPos"],this.outputShape=t.inShape;var e=t.strideHeight,n=t.strideWidth,r=t.dilationHeight,o=t.effectiveFilterHeight,a=t.effectiveFilterWidth,i=o-1-t.padInfo.top,s=a-1-t.padInfo.left,u=o*a-1;this.userCode="\n const ivec2 pads = ivec2("+i+", "+s+");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n\n ivec2 dyRCCorner = coords.yz - pads;\n int dyRCorner = dyRCCorner.x;\n int dyCCorner = dyRCCorner.y;\n\n // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < "+o+";\n wR += "+r+") {\n float dyR = float(dyRCorner + wR) / "+e+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+a+"; wC++) {\n float dyC = float(dyCCorner + wC) / "+n+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(b, idyR, idyC, d);\n int maxPosValue = "+u+" - int(getMaxPos(b, idyR, idyC, d));\n\n // Get the current value, check it against the value from the\n // position matrix.\n int curPosValue = wR * "+a+" + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n setOutput(dotProd);\n }\n "}}(),xi=function(){return function(t){this.variableNames=["dy","maxPos"],this.outputShape=t.inShape;var e=t.strideDepth,n=t.strideHeight,r=t.strideWidth,o=t.dilationDepth,a=t.dilationHeight,i=t.dilationWidth,s=t.effectiveFilterDepth,u=t.effectiveFilterHeight,l=t.effectiveFilterWidth,c=s-1-t.padInfo.front,h=u-1-t.padInfo.top,p=l-1-t.padInfo.left,f=s*u*l-1;this.userCode="\n const ivec3 pads = ivec3("+c+", "+h+", "+p+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n int dyDCorner = dyCorner.x;\n int dyRCorner = dyCorner.y;\n int dyCCorner = dyCorner.z;\n\n // Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get\n // dx(xD, xR, xC, ch).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int wD = 0; wD < "+s+";\n wD += "+o+") {\n float dyD = float(dyDCorner + wD) / "+e+".0;\n\n if (dyD < 0.0 || dyD >= "+t.outDepth+".0 || fract(dyD) > 0.0) {\n continue;\n }\n int idyD = int(dyD);\n\n for (int wR = 0; wR < "+u+";\n wR += "+a+") {\n float dyR = float(dyRCorner + wR) / "+n+".0;\n\n if (dyR < 0.0 || dyR >= "+t.outHeight+".0 ||\n fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < "+l+";\n wC += "+i+") {\n float dyC = float(dyCCorner + wC) / "+r+".0;\n\n if (dyC < 0.0 || dyC >= "+t.outWidth+".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n int maxPosValue = "+f+" -\n int(getMaxPos(batch, idyD, idyR, idyC, ch));\n\n // Get the current value, check it against the value from the\n // position matrix.\n int curPosValue =\n wD * "+u+" * "+l+" +\n wR * "+l+" + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n }\n setOutput(dotProd);\n }\n "}}(),bi=function(){return function(t,e,n,r,o,a,i){void 0===n&&(n=!1),void 0===r&&(r=!1),void 0===o&&(o=!1),void 0===a&&(a=null),void 0===i&&(i=!1),this.variableNames=["matrixA","matrixB"],this.usesPackedTextures=!0,this.outputShape=e;var s=n?t[1]:t[2],u=Math.ceil(s/2),l=n?"i * 2, rc.y":"rc.y, i * 2",c=r?"rc.z, i * 2":"i * 2, rc.z",h=n?["a.xxyy","a.zzww"]:["a.xxzz","a.yyww"],p=r?["b.xzxz","b.ywyw"]:["b.xyxy","b.zwzw"],f="",d="";a&&(f=i?"vec4 activation(vec4 a) {\n vec4 b = getPreluActivationWeightsAtOutCoords();\n "+a+"\n }":"vec4 activation(vec4 x) {\n "+a+"\n }",d="result = activation(result);");var v=o?"result += getBiasAtOutCoords();":"";o&&this.variableNames.push("bias"),i&&this.variableNames.push("preluActivationWeights"),this.userCode="\n "+f+"\n\n const float sharedDimension = "+u+".0;\n\n vec4 dot2x2ARowBCol(ivec3 rc) {\n vec4 result = vec4(0);\n for (int i = 0; i < "+u+"; i++) {\n vec4 a = getMatrixA(rc.x, "+l+");\n vec4 b = getMatrixB(rc.x, "+c+");\n\n // These swizzled products need to be separately added.\n // See: https://github.com/tensorflow/tfjs/issues/1735\n result += ("+h[0]+" * "+p[0]+");\n result += ("+h[1]+" * "+p[1]+");\n }\n return result;\n }\n\n void main() {\n ivec3 rc = getOutputCoords();\n vec4 result = dot2x2ARowBCol(rc);\n\n "+v+"\n\n "+d+"\n\n setOutput(result);\n }\n "}}(),wi=function(){function t(t,e,n){this.variableNames=["probs"],this.outputShape=[t,n],this.userCode="\n uniform float seed;\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n\n float r = random(seed);\n float cdf = 0.0;\n\n for (int i = 0; i < "+(e-1)+"; i++) {\n cdf += getProbs(batch, i);\n\n if (r < cdf) {\n setOutput(float(i));\n return;\n }\n }\n\n // If no other event happened, last event happened.\n setOutput(float("+(e-1)+"));\n }\n "}return t.prototype.getCustomSetupFunc=function(t){var e=this;return function(n,r){null==e.seedLoc&&(e.seedLoc=n.getUniformLocation(r,"seed")),n.gl.uniform1f(e.seedLoc,t)}},t}(),Ci=function(){return function(t,e,n,r){this.variableNames=["indices"],this.outputShape=[t,e],this.userCode="\n void main() {\n ivec2 coords = getOutputCoords();\n int index = round(getIndices(coords.x));\n setOutput(mix(float("+r+"), float("+n+"),\n float(index == coords.y)));\n }\n "}}(),Ei=function(){return function(t){this.variableNames=["A"],this.outputShape=t;var e=t.length;if(0===e)this.userCode="\n void main() {\n setOutput(vec4(getA(), 0., 0., 0.));\n }\n ";else{var n=Mo("rc",e),r=Xo(e),o=function(t,e,n){if(1===t)return"rc > "+e[0];for(var r="",o=t-2;o= "+e[o],o= "+e+";\n bool rEdge = rp1 >= "+n+";\n "}(e,t[t.length-1],t[t.length-2],n),i=function(t,e){var n=t.length,r=function(t,e){for(var n=[],r=0;r<=1;r++)for(var o=0;o<=1;o++){for(var a=(0===r?"r":"rp1")+", "+(0===o?"c":"cp1"),i=2;i= "+t[0]+" ? 0. : getA(rc + 1),\n 0, 0":"getA("+r[0]+"),\n cEdge ? 0. : getA("+r[1]+"),\n rEdge ? 0. : getA("+r[2]+"),\n rEdge || cEdge ? 0. : getA("+r[3]+")"}(t,n);this.userCode="\n void main() {\n "+r+" rc = getOutputCoords();\n\n if("+o+") {\n setOutput(vec4(0));\n } else {\n "+a+"\n\n setOutput(vec4("+i+"));\n }\n }\n "}}}();var Ri=function(){return function(t,e,n){this.variableNames=["x"],this.outputShape=e.map(function(e,n){return e[0]+t[n]+e[1]});var r=t.length,o=Xo(r),a=e.map(function(t){return t[0]}).join(","),i=e.map(function(e,n){return e[0]+t[n]}).join(","),s=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,r);this.userCode=1!==r?"\n "+o+" start = "+o+"("+a+");\n "+o+" end = "+o+"("+i+");\n\n void main() {\n "+o+" outC = getOutputCoords();\n if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {\n setOutput(float("+n+"));\n } else {\n "+o+" coords = outC - start;\n setOutput(getX("+s+"));\n }\n }\n ":"\n int start = "+a+";\n int end = "+i+";\n\n void main() {\n int outC = getOutputCoords();\n if (outC < start || outC >= end) {\n setOutput(float("+n+"));\n } else {\n setOutput(getX(outC - start));\n }\n }\n "}}(),Ii=function(){return function(t,e,n){this.variableNames=["x"],this.usesPackedTextures=!0,this.outputShape=e.map(function(e,n){return e[0]+t[n]+e[1]});for(var r=t.length,o=Xo(r),a=e.map(function(t){return t[0]}).join(","),i=e.map(function(e,n){return e[0]+t[n]}).join(","),s=Mo("rc",r),u=Mo("source",r),l=s[r-1]+" < "+this.outputShape[r-1],c=1===r?"source":"vec2("+u.slice(-2).join()+")",h=[o+" rc = outputLoc;",s[r-1]+" += 1;\n if("+l+") {\n ",1===r?"":"}\n rc = outputLoc;\n "+s[r-2]+" += 1;\n if("+s[r-2]+" < "+this.outputShape[r-2]+") {",1===r?"":" "+s[r-1]+" += 1;\n if("+l+") {"],p=1===r?"rc < start || rc >= end":"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))",f="",d=0,v=1===r?2:4;d= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+l+";\n wC += "+s+") {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float value = getX(batch, xR, xC, d);\n\n // If a min / max value has already been found, use it. If not,\n // use the current value.\n float currMinMaxValue = mix(\n value, minMaxValue, minMaxValueFound);\n if (value >= currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition = wR * "+l+" + wC;\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n ";else{var d=e+"("+e+"("+e+"(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"avg"===e&&(d="avgValue / count");var v=4*Math.floor(r/4),m=r%4,g="\n if ("+p+") {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = max(values, minMaxValue);\n }\n ";this.userCode="\n const ivec2 strides = ivec2("+o+", "+a+");\n const ivec2 pads = ivec2("+c+", "+h+");\n const float initializationValue = "+f+";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float count = 0.0;\n\n float getValue(int batch, int xR, int xC, int d) {\n if (xC < 0 || xC >= "+t.inWidth+") {\n return initializationValue;\n }\n count += 1.0;\n return getX(batch, xR, xC, d);\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // max/min x(?, ?, d) to get y(yR, yC, d).\n // ? = to be determined\n vec4 minMaxValue = vec4("+f+");\n float avgValue = 0.0;\n count = 0.0;\n\n for (int wR = 0; wR < "+u+";\n wR += "+i+") {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+v+"; wC += 4) {\n int xC = xCCorner + wC * "+s+";\n\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n getValue(batch, xR, xC + 2 * "+s+", d),\n getValue(batch, xR, xC + 3 * "+s+", d)\n );\n\n "+g+"\n }\n\n int xC = xCCorner + "+v+";\n if ("+(1===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n "+g+"\n } else if ("+(2===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n initializationValue,\n initializationValue\n );\n\n "+g+"\n } else if ("+(3===m)+") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + "+s+", d),\n getValue(batch, xR, xC + 2 * "+s+", d),\n initializationValue\n );\n\n "+g+"\n }\n }\n setOutput("+d+");\n }\n "}}}(),Ni=function(){return function(t,e,n){if(this.variableNames=["x"],"avg"===e&&n)throw new Error("Cannot compute positions for average pool.");var r=t.filterWidth,o=t.strideDepth,a=t.strideHeight,i=t.strideWidth,s=t.dilationDepth,u=t.dilationHeight,l=t.dilationWidth,c=t.effectiveFilterDepth,h=t.effectiveFilterHeight,p=t.effectiveFilterWidth,f=t.padInfo.front,d=t.padInfo.top,v=t.padInfo.left;this.outputShape=t.outShape;var m="avg"===e,g="0.0";if(m||(g="-1.0 / 1e-20"),n)this.userCode="\n const ivec3 strides =\n ivec3("+o+", "+a+", "+i+");\n const ivec3 pads = ivec3("+f+", "+d+", "+v+");\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xDCorner = xCorner.x;\n int xRCorner = xCorner.y;\n int xCCorner = xCorner.z;\n\n // max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch).\n // ? = to be determined\n float minMaxValue = 0.0;\n float minMaxValueFound = 0.0;\n int minMaxPosition = 0;\n\n for (int wD = 0; wD < "+c+";\n wD += "+s+") {\n int xD = xDCorner + wD;\n\n if (xD < 0 || xD >= "+t.inDepth+") {\n continue;\n }\n\n for (int wR = 0; wR < "+h+";\n wR += "+u+") {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+p+";\n wC += "+l+") {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= "+t.inWidth+") {\n continue;\n }\n\n float value = getX(batch, xD, xR, xC, ch);\n\n // If a min / max value has already been found, use it. If not,\n // use the current value.\n float currMinMaxValue = mix(\n value, minMaxValue, minMaxValueFound);\n if (value >= currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition =\n wD * "+h+" * "+p+" +\n wR * "+p+" + wC;;\n }\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n ";else{var y=e+"("+e+"("+e+"(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"avg"===e&&(y="avgValue / count");var x=4*Math.floor(r/4),b=r%4,w="\n if ("+m+") {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = max(values, minMaxValue);\n }\n ";this.userCode="\n const ivec3 strides =\n ivec3("+o+", "+a+", "+i+");\n const ivec3 pads = ivec3("+f+", "+d+", "+v+");\n const float initializationValue = "+g+";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float count = 0.0;\n\n float getValue(int batch, int xD, int xR, int xC, int ch) {\n if (xC < 0 || xC >= "+t.inWidth+") {\n return initializationValue;\n }\n count += 1.0;\n return getX(batch, xD, xR, xC, ch);\n }\n\n void main() {\n ivec5 coords = getOutputCoords();\n int batch = coords.x;\n int ch = coords.u;\n\n ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n int xDCorner = xCorner.x;\n int xRCorner = xCorner.y;\n int xCCorner = xCorner.z;\n\n // max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch).\n // ? = to be determined\n vec4 minMaxValue = vec4("+g+");\n float avgValue = 0.0;\n count = 0.0;\n\n for (int wD = 0; wD < "+c+";\n wD += "+s+") {\n int xD = xDCorner + wD;\n\n if (xD < 0 || xD >= "+t.inDepth+") {\n continue;\n }\n\n for (int wR = 0; wR < "+h+";\n wR += "+u+") {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= "+t.inHeight+") {\n continue;\n }\n\n for (int wC = 0; wC < "+x+"; wC += 4) {\n int xC = xCCorner + wC * "+l+";\n\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + "+l+", ch),\n getValue(batch, xD, xR, xC + 2 * "+l+", ch),\n getValue(batch, xD, xR, xC + 3 * "+l+", ch)\n );\n\n "+w+"\n }\n\n int xC = xCCorner + "+x+";\n if ("+(1===b)+") {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n "+w+"\n } else if ("+(2===b)+") {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + "+l+", ch),\n initializationValue,\n initializationValue\n );\n\n "+w+"\n } else if ("+(3===b)+") {\n vec4 values = vec4(\n getValue(batch, xD, xR, xC, ch),\n getValue(batch, xD, xR, xC + "+l+", ch),\n getValue(batch, xD, xR, xC + 2 * "+l+", ch),\n initializationValue\n );\n\n "+w+"\n }\n }\n setOutput("+y+");\n }\n }\n "}}}(),Si=function(){return function(t,e){this.variableNames=["x"];var n=t.windowSize,r=t.batchSize,o=t.inSize,a=Math.ceil(o/n);this.outputShape=[r,a];var i="0.0",s="";"prod"===e?i="1.0":"min"===e?(i="1.0 / 1e-20",s="min"):"max"===e&&(i="-1.0 / 1e-20",s="max");var u=e+"("+e+"("+e+"(minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"sum"===e?u="sumValue":"prod"===e?u="prodValue":"all"===e?u="allValue":"any"===e&&(u="anyValue");var l=4*Math.floor(n/4),c=n%4,h="\n if ("+("sum"===e)+") {\n sumValue += dot(values, ones);\n } else if ("+("prod"===e)+") {\n vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);\n prodValue *= tmp[0] * tmp[1];\n } else {\n minMaxValue = "+s+"(values, minMaxValue);\n }\n ",p="vec4";"all"===e?(i="1.0",h="\n bool reducedAllValue = all(values);\n float floatedReducedAllValue = float(reducedAllValue);\n allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);\n ",p="bvec4"):"any"===e&&(i="0.0",h="\n bool reducedAnyValue = any(values);\n float floatedReducedAnyValue = float(reducedAnyValue);\n anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);\n ",p="bvec4");var f="";o%n>0&&(f="\n if (inIdx < 0 || inIdx >= "+o+") {\n return initializationValue;\n }\n "),this.userCode="\n const float initializationValue = "+i+";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int inIdx) {\n "+f+"\n return getX(batch, inIdx);\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * "+n+";\n\n vec4 minMaxValue = vec4("+i+");\n float prodValue = 1.0;\n float sumValue = 0.0;\n float allValue = 1.0;\n float anyValue = 0.0;\n\n for (int i = 0; i < "+l+"; i += 4) {\n int inIdx = inOffset + i;\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n getValue(batch, inIdx + 3)\n );\n\n "+h+"\n }\n\n int inIdx = inOffset + "+l+";\n if ("+(1===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n "+h+"\n } else if ("+(2===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n initializationValue,\n initializationValue\n );\n\n "+h+"\n } else if ("+(3===c)+") {\n "+p+" values = "+p+"(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n initializationValue\n );\n\n "+h+"\n }\n setOutput("+u+");\n }\n "}}(),Ai=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;for(var n="",r=0;r<4;r++){var o="thisRC = rc;";r%2==1&&(o+="thisRC.z += 1;"),r>1&&(o+="thisRC.y += 1;"),n+="\n "+o+"\n "+(r>0?"if(thisRC.y < rows && thisRC.z < cols){":"")+"\n int flatIndex = getFlatIndex(thisRC);\n\n ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex);\n vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z));\n\n result["+r+"] =\n getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);\n "+(r>0?"}":"")+"\n "}this.userCode="\n \n ivec3 inputCoordsFromReshapedOutCoords(int index) {\n "+Po(["r","c","d"],e)+"\n return ivec3(r, c, d);\n }\n \n "+Lo(t)+"\n\n void main() {\n ivec3 rc = getOutputCoords();\n\n vec4 result = vec4(0.);\n\n ivec3 thisRC;\n int rows = "+t[1]+";\n int cols = "+t[2]+";\n\n "+n+"\n\n setOutput(result);\n }\n "}}();var Ti=function(){return function(t,e,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;var r=e.shape,o=r[1],a=r[2],i=t.shape,s=i[1],u=i[2],l=[n&&s>1?o-1:o,n&&u>1?a-1:a],c=[n&&s>1?s-1:s,n&&u>1?u-1:u],h=l[0]/c[0],p=l[1]/c[1],f=1/h,d=1/p,v=2*Math.ceil(f)+2,m=2*Math.ceil(d)+2;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n int r = coords[1];\n int c = coords[2];\n\n float accumulator = 0.0;\n\n const float heightScale = float("+h+");\n const float widthScale = float("+p+");\n\n const float invHeightScale = float("+f+");\n const float invWidthScale = float("+d+");\n\n const int winHeight = int("+v+");\n const int winWidth = int("+m+");\n\n // Compute bounds for where in dy we will look\n float startRLerp = floor(float(r) * invHeightScale);\n int startDyR = int(startRLerp - float(winHeight / 2));\n\n float startCLerp = floor(float(c) * invWidthScale);\n int startDyC = int(startCLerp - float(winWidth / 2));\n\n // Loop over dy\n for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n int dyR = dyROffset + startDyR;\n\n // Guard against the window exceeding the bounds of dy\n if (dyR < 0 || dyR >= "+s+") {\n continue;\n }\n\n for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n int dyC = dyCOffset + startDyC;\n\n // Guard against the window exceeding the bounds of dy\n if (dyC < 0 || dyC >= "+u+") {\n continue;\n }\n\n float dxR = float(dyR) * heightScale;\n int topDxRIndex = int(floor(dxR));\n int bottomDxRIndex = int(min(ceil(dxR), "+(o-1)+".0));\n float dxRLerp = dxR - float(topDxRIndex);\n float inverseDxRLerp = 1.0 - dxRLerp;\n\n float dxC = float(dyC) * widthScale;\n int leftDxCIndex = int(floor(dxC));\n int rightDxCIndex = int(min(ceil(dxC), "+(a-1)+".0));\n float dxCLerp = dxC - float(leftDxCIndex);\n float inverseDxCLerp = 1.0 - dxCLerp;\n\n if (r == topDxRIndex && c == leftDxCIndex) {\n // topLeft\n accumulator +=\n getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp;\n }\n\n if (r == topDxRIndex && c == rightDxCIndex) {\n // topRight\n accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp;\n }\n\n if (r == bottomDxRIndex && c == leftDxCIndex) {\n // bottomLeft\n accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp;\n }\n\n if (r == bottomDxRIndex && c == rightDxCIndex) {\n // bottomRight\n accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp;\n }\n }\n }\n // End loop over dy\n\n setOutput(accumulator);\n }\n "}}(),Di=function(){return function(t,e,n,r){this.variableNames=["A"],this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n];this.userCode="\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+");\n const vec2 inputShapeRC = vec2("+a+".0, "+i+".0);\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n ivec2 yRC = coords.yz;\n\n // Fractional source index.\n vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the four integer indices.\n ivec2 sourceFloorRC = ivec2(sourceFracIndexRC);\n ivec2 sourceCeilRC = ivec2(\n min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);\n float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);\n float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);\n float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);\n\n vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);\n\n float top = topLeft + (topRight - topLeft) * fracRC.y;\n float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;\n float newValue = top + (bottom - top) * fracRC.x;\n\n setOutput(newValue);\n }\n "}}(),_i=function(){return function(t,e,n,r){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n];this.userCode="\n const vec3 effectiveInputOverOutputRatioRC = vec3(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+",\n "+u[1]/l[1]+");\n const vec3 inputShapeRC = vec3("+a+".0, "+i+".0,\n "+i+".0);\n\n float getAValue(int b, int r, int c, int d) {\n return getChannel(getA(b, r, c, d), vec2(c, d));\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n // Calculate values for next column in yRC.z.\n ivec3 yRC = coords.yzz + ivec3(0, 0, 1);\n\n // Fractional source index.\n vec3 sourceFracIndexRC = vec3(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the four integer indices.\n ivec3 sourceFloorRC = ivec3(sourceFracIndexRC);\n ivec3 sourceCeilRC = ivec3(\n min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n \n // Should we calculate next column and row elements in 2x2 packed cell.\n bool hasNextCol = d < "+(s-1)+"; \n bool hasNextRow = coords.z < "+(n-1)+";\n\n // In parallel, construct four corners for all four components in\n // packed 2x2 cell.\n vec4 topLeft = vec4(\n getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d),\n hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n vec4 bottomLeft = vec4(\n getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d),\n hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n vec4 topRight = vec4(\n getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d),\n hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n vec4 bottomRight = vec4(\n getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d),\n hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1)\n : 0.0,\n hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d)\n : 0.0,\n (hasNextRow && hasNextCol) ?\n getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC);\n\n vec4 top = mix(topLeft, topRight, fracRC.yyzz);\n vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz);\n vec4 newValue = mix(top, bottom, fracRC.x);\n\n setOutput(newValue);\n }\n "}}(),Oi=function(){return function(t,e,n){this.variableNames=["dy"],this.outputShape=[],this.outputShape=e.shape;var r=e.shape,o=r[1],a=r[2],i=t.shape,s=i[1],u=i[2],l=[n&&s>1?o-1:o,n&&u>1?a-1:a],c=[n&&s>1?s-1:s,n&&u>1?u-1:u],h=l[0]/c[0],p=l[1]/c[1],f=1/h,d=1/p,v=2*Math.ceil(f)+2,m=2*Math.ceil(d)+2;this.userCode="\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n int r = coords[1];\n int c = coords[2];\n\n float accumulator = 0.0;\n\n const float heightScale = float("+h+");\n const float widthScale = float("+p+");\n\n const float invHeightScale = float("+f+");\n const float invWidthScale = float("+d+");\n\n const int winHeight = int("+v+");\n const int winWidth = int("+m+");\n\n // Compute bounds for where in dy we will look\n float startRLerp = floor(float(r) * invHeightScale);\n int startDyR = int(floor(startRLerp - float(winHeight / 2)));\n\n float startCLerp = floor(float(c) * invWidthScale);\n int startDyC = int(floor(startCLerp - float(winWidth / 2)));\n\n // Loop over dy\n for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n int dyR = dyROffset + startDyR;\n\n // Guard against the window exceeding the bounds of dy\n if (dyR < 0 || dyR >= "+s+") {\n continue;\n }\n\n for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n int dyC = dyCOffset + startDyC;\n\n // Guard against the window exceeding the bounds of dy\n if (dyC < 0 || dyC >= "+u+") {\n continue;\n }\n\n float sourceFracRow =\n float("+l[0]+") *\n (float(dyR) / float("+c[0]+"));\n\n float sourceFracCol =\n float("+l[1]+") *\n (float(dyC) / float("+c[1]+"));\n\n int sourceNearestRow = int(min(\n float(int("+o+") - 1),\n "+n+" ? float(round(sourceFracRow)) :\n float(floor(sourceFracRow))));\n\n int sourceNearestCol = int(min(\n float(int("+a+") - 1),\n "+n+" ? float(round(sourceFracCol)) :\n float(floor(sourceFracCol))));\n\n if (r == sourceNearestRow && c == sourceNearestCol) {\n accumulator += getDy(b, dyR, dyC, d);\n }\n }\n }\n // End loop over dy\n\n setOutput(accumulator);\n }\n "}}(),Fi=function(){return function(t,e,n,r){this.variableNames=["A"],this.outputShape=[];var o=t[0],a=t[1],i=t[2],s=t[3];this.outputShape=[o,e,n,s];var u=[r&&e>1?a-1:a,r&&n>1?i-1:i],l=[r&&e>1?e-1:e,r&&n>1?n-1:n],c=r?"0.5":"0.0";this.userCode="\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n "+u[0]/l[0]+",\n "+u[1]/l[1]+");\n const vec2 inputShapeRC = vec2("+a+".0, "+i+".0);\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n ivec2 yRC = coords.yz;\n\n // Fractional source index.\n vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the coordinators of nearest neighbor point.\n ivec2 sourceNearestRC = ivec2(\n min(inputShapeRC - 1.0, floor(sourceFracIndexRC + "+c+")));\n\n float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);\n\n setOutput(newValue);\n }\n "}}(),Mi=function(){return function(t,e){this.variableNames=["x"];var n=t.length;if(n>4)throw new Error("WebGL backend: Reverse of rank-"+n+" tensor is not yet supported");if(this.outputShape=t,1!==n){var r=t.map(function(n,r){return function(n){return-1!==e.indexOf(n)&&1!==t[n]?t[n]+" - coords["+n+"] - 1":"coords["+n+"]"}(r)}).join(","),o=Xo(n);this.userCode="\n void main() {\n "+o+" coords = getOutputCoords();\n setOutput(getX("+r+"));\n }\n "}else this.userCode="\n void main() {\n int coord = getOutputCoords();\n setOutput(getX("+t[0]+" - coord - 1));\n }\n "}}(),Bi=function(){return function(t,e){this.variableNames=["x"],this.usesPackedTextures=!0;var n=t.length;if(n>4)throw new Error("WebGL backend: Reverse of rank-"+n+" tensor is not yet supported");this.outputShape=t;var r=Mo("rc",n),o=r[n-1]+" + 1 < "+this.outputShape[n-1],a=r[n-2]+" + 1 < "+this.outputShape[n-2],i=Xo(n);function s(n){var r=t.map(function(r,o){return function(n,r){return-1!==e.indexOf(n)&&1!==t[n]?t[n]+" - "+r[n]+" - 1":""+r[n]}(o,n)});return"getChannel(getX("+r.join(",")+"), vec2("+r.slice(-2).join(",")+"))"}this.userCode=1===n?"\n void main(){\n int rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = getChannel(getX("+t[0]+" - rc - 1),\n "+t[0]+" - rc - 1);\n if("+o+"){\n result.g = getChannel(getX("+t[0]+" - (rc + 1) - 1),\n "+t[0]+" - (rc + 1) - 1);\n }\n setOutput(result);\n }\n ":"\n void main() {\n "+i+" rc = getOutputCoords();\n vec4 result = vec4(0.);\n result.r = "+function(t){return s(t)}(r.slice())+";\n if("+o+"){\n result.g = "+function(t){return t[n-1]="("+t[n-1]+" + 1)",s(t)}(r.slice())+";\n }\n if("+a+") {\n result.b = "+function(t){return t[n-2]="("+t[n-2]+" + 1)",s(t)}(r.slice())+";\n if("+o+") {\n result.a = "+function(t){return t[n-1]="("+t[n-1]+" + 1)",t[n-2]="("+t[n-2]+" + 1)",s(t)}(r.slice())+";\n }\n }\n setOutput(result);\n }\n "}}(),Pi=function(){return function(t,e,n,r,o,a,i){void 0===i&&(i=!0),this.variableNames=["updates","indices","defaultValue"],this.outputShape=a;var s=Xo(o.length),u=Xo(a.length),l="";1===n?l="i":2===n&&(l="i, j");var c="getIndices("+l+")",h="";1===r?h="i":2===r&&(h="i, coords[1]");var p="getUpdates("+h+")",f=e>1?"strides[j]":"strides";this.userCode="\n "+s+" strides = "+s+"("+o+");\n\n void main() {\n "+u+" coords = getOutputCoords();\n float sum = 0.0;\n bool found = false;\n for (int i = 0; i < "+t+"; i++) {\n int flattenedIndex = 0;\n for (int j = 0; j < "+e+"; j++) {\n int index = round("+c+");\n flattenedIndex += index * "+f+";\n }\n if (flattenedIndex == coords[0]) {\n sum += "+p+";\n found = true;\n }\n }\n setOutput(mix(getDefaultValue(), sum, float(found)));\n }\n "}}(),Li=function(){return function(t,e){this.variableNames=["x","segmentIds"];var n=t.windowSize,r=t.batchSize,o=t.inSize,a=t.numSegments,i=a*Math.ceil(o/n);this.outputShape=[r,i];var s=4*Math.floor(n/4),u=n%4,l="\n sumValue += dot(values, segFilter);\n ",c="";o%n>0&&(c="\n if (inIdx < 0 || inIdx >= "+o+") {\n return initializationValue;\n }\n ");var h="";o%n>0&&(h="\n if (inIdx < 0 || inIdx >= "+o+") {\n return -1.0;\n }\n "),this.userCode="\n const float initializationValue = 0.0;\n\n float getValue(int batch, int inIdx) {\n "+c+"\n return getX(batch, inIdx);\n }\n\n float getSegmentIdAtIndex(int inIdx) {\n "+h+"\n return getSegmentIds(inIdx);\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = int(floor(float(outIdx) / float(\n "+a+")) * float("+n+"));\n int currentSeg = int(mod(float(outIdx), float("+a+")));\n\n float sumValue = 0.0;\n\n for (int i = 0; i < "+s+"; i += 4) {\n int inIdx = inOffset + i;\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n getValue(batch, inIdx + 3)\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0\n );\n\n "+l+"\n }\n\n int inIdx = inOffset + "+s+";\n if ("+(1===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n\n int inIdxSeg = int(getSegmentIdAtIndex(inIdx));\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n 0,\n 0,\n 0\n );\n\n "+l+"\n } else if ("+(2===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n initializationValue,\n initializationValue\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n 0,\n 0\n );\n\n "+l+"\n } else if ("+(3===u)+") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n initializationValue\n );\n\n vec4 segFilter = vec4(\n int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n 0\n );\n\n "+l+"\n }\n setOutput(sumValue);\n }\n "}}(),Wi=function(){return function(t,e,n){var r,o;if(this.variableNames=["c","a","b"],this.outputShape=e,n>4)throw Error("Where for rank "+n+" is not yet supported");if(1===n)o="resRC",r="resRC";else{for(var a=["resRC.x","resRC.y","resRC.z","resRC.w"],i=[],s=[],u=0;u= 1.0) {\n setOutput(getA("+o+"));\n } else {\n setOutput(getB("+o+"));\n }\n }\n "}}(),Ui=function(){function t(t){this.variableNames=["source"],this.outputShape=t,this.rank=t.length;var e,n=Xo(this.rank),r="uniform int start["+this.rank+"];",o=function(t){if(1===t)return"sourceLoc";if(t<=6)return Vi.slice(0,t).map(function(t){return"sourceLoc."+t}).join(",");throw Error("Slicing for rank "+t+" is not yet supported")}(this.rank);e="\n "+n+" sourceLoc;\n "+n+" coords = getOutputCoords();\n "+t.map(function(t,e){return"sourceLoc."+Vi[e]+" = start["+e+"] + coords."+Vi[e]+";"}).join("\n")+"\n ",this.userCode="\n "+r+"\n void main() {\n "+e+"\n setOutput(getSource("+o+"));\n }\n "}return t.prototype.getCustomSetupFunc=function(t){var e=this;if(t.length!==this.rank)throw Error("The rank ("+this.rank+") of the program must match the length of start ("+t.length+")");return function(n,r){null==e.startLoc&&(e.startLoc=n.getUniformLocationNoThrow(r,"start"),null==e.startLoc)||n.gl.uniform1iv(e.startLoc,t)}},t}(),Vi=["x","y","z","w","u","v"];var zi=function(){function t(t){this.variableNames=["source"],this.usesPackedTextures=!0,this.outputShape=t,this.rank=t.length;var e=Xo(this.rank),n=Mo("coords",this.rank),r=Mo("sourceLoc",this.rank),o=1===this.rank?"sourceLoc":"vec2("+r.slice(-2).join()+")",a="getChannel(getSource("+r.join()+"), "+o+")",i="\n result.x = "+a+";\n if (++"+n[this.rank-1]+" < "+t[this.rank-1]+") {\n ++"+r[this.rank-1]+";\n result.y = "+a+";\n --"+r[this.rank-1]+";\n }\n ",s=1===this.rank?"":"\n --"+n[this.rank-1]+";\n if (++"+n[this.rank-2]+" < "+t[this.rank-2]+") {\n ++"+r[this.rank-2]+";\n result.z = "+a+";\n if (++"+n[this.rank-1]+" < "+t[this.rank-1]+") {\n ++"+r[this.rank-1]+";\n result.w = "+a+";\n }\n }\n ",u=this.rank<=4?"sourceLoc = coords +\n "+e+"("+t.map(function(t,e){return"start["+e+"]"}).join()+");":t.map(function(t,e){return r[e]+" = "+n[e]+" + start["+e+"];"}).join("\n");this.userCode="\n uniform int start["+this.rank+"];\n void main() {\n "+e+" coords = getOutputCoords();\n "+e+" sourceLoc;\n "+u+" \n vec4 result = vec4(0.);\n "+i+"\n "+s+"\n setOutput(result);\n }\n "}return t.prototype.getCustomSetupFunc=function(t){var e=this;if(t.length!==this.rank)throw Error("The rank ("+this.rank+") of the program must match the length of start ("+t.length+")");return function(n,r){null==e.startLoc&&(e.startLoc=n.getUniformLocationNoThrow(r,"start"),null==e.startLoc)||n.gl.uniform1iv(e.startLoc,t)}},t}(),Gi=function(){return function(t,e,n){this.variableNames=["x"],this.outputShape=n;var r=n.length,o=Xo(n.length),a=Xo(n.length),i="";if(1===r)i="coords * strides + begin";else{var s=0;i=n.map(function(t,e){return s++,1===n.length?"coords * strides["+e+"] + begin["+e+"]":"coords["+(s-1)+"] * strides["+e+"] + begin["+e+"]"}).join(",")}this.userCode="\n "+o+" begin = "+o+"("+t+");\n "+o+" strides = "+o+"("+e+");\n\n void main() {\n "+a+" coords = getOutputCoords();\n setOutput(getX("+i+"));\n }\n "}}(),Hi=function(){function t(t){this.gpgpu=t,this.numUsedTextures=0,this.numFreeTextures=0,this.freeTextures={},this.logEnabled=!1,this.usedTextures={}}return t.prototype.acquireTexture=function(t,e,n){var r,o=qi(e,n),a=$i(t,o,n);if(a in this.freeTextures||(this.freeTextures[a]=[]),a in this.usedTextures||(this.usedTextures[a]=[]),this.freeTextures[a].length>0){this.numFreeTextures--,this.numUsedTextures++,this.log();var i=this.freeTextures[a].shift();return this.usedTextures[a].push(i),i}return this.numUsedTextures++,this.log(),o===Tt.PACKED_2X2_FLOAT32?r=this.gpgpu.createPackedMatrixTexture(t[0],t[1]):o===Tt.PACKED_2X2_FLOAT16?r=this.gpgpu.createFloat16PackedMatrixTexture(t[0],t[1]):o===Tt.UNPACKED_FLOAT32?r=this.gpgpu.createFloat32MatrixTexture(t[0],t[1]):o===Tt.UNPACKED_FLOAT16?r=this.gpgpu.createFloat16MatrixTexture(t[0],t[1]):o===Tt.PACKED_4X1_UNSIGNED_BYTE&&(r=this.gpgpu.createUnsignedBytesMatrixTexture(t[0],t[1])),this.usedTextures[a].push(r),r},t.prototype.releaseTexture=function(t,e,n,r){if(null!=this.freeTextures){var o=$i(e,qi(n,r),r);o in this.freeTextures||(this.freeTextures[o]=[]),this.freeTextures[o].push(t),this.numFreeTextures++,this.numUsedTextures--;var a=this.usedTextures[o],i=a.indexOf(t);if(i<0)throw new Error("Cannot release a texture that was never provided by this texture manager");a.splice(i,1),this.log()}},t.prototype.log=function(){if(this.logEnabled){var t=this.numFreeTextures+this.numUsedTextures;console.log("Free/Used",this.numFreeTextures+" / "+this.numUsedTextures,"("+t+")")}},t.prototype.getNumUsedTextures=function(){return this.numUsedTextures},t.prototype.getNumFreeTextures=function(){return this.numFreeTextures},t.prototype.dispose=function(){var t=this;if(null!=this.freeTextures){for(var e in this.freeTextures)this.freeTextures[e].forEach(function(e){t.gpgpu.deleteMatrixTexture(e)});for(var e in this.usedTextures)this.usedTextures[e].forEach(function(e){t.gpgpu.deleteMatrixTexture(e)});this.freeTextures=null,this.usedTextures=null,this.numUsedTextures=0,this.numFreeTextures=0}},t}();function qi(t,e){if(t===At.UPLOAD)return Tt.PACKED_2X2_FLOAT32;if(t===At.RENDER||null==t)return function(t){return a().getBool("WEBGL_RENDER_FLOAT32_ENABLED")?t?Tt.PACKED_2X2_FLOAT32:Tt.UNPACKED_FLOAT32:t?Tt.PACKED_2X2_FLOAT16:Tt.UNPACKED_FLOAT16}(e);if(t===At.DOWNLOAD||t===At.PIXELS)return Tt.PACKED_4X1_UNSIGNED_BYTE;throw new Error("Unknown logical texture type "+t)}function $i(t,e,n){return t[0]+"_"+t[1]+"_"+e+"_"+n}var Ki=function(){return function(t,e){this.variableNames=["A"];for(var n=new Array(t.length),r=0;r5)throw Error("Tile for rank "+e+" is not yet supported");if(1===e)return"imod(resRC, "+t[0]+")";for(var n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u"],r=[],o=0;o6)throw Error("Transpose for rank "+e+" is not yet supported");for(var n=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u","resRC.v"],r=new Array(e),o=0;o6)throw Error("Packed transpose for rank "+this.rank+" is not yet supported.");var o=Xo(this.rank),a=Fo("rc",this.rank),i=new Array(this.rank);for(r=0;r= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n";var is="return -x;",ss="return ceil(x);",us="return floor(x);",ls="return exp(x);",cs="return exp(x) - 1.0;",hs=Zi+"\n return sin(x);\n",ps=Zi+"\n return cos(x);\n",fs=Zi+"\n if (abs(x) > 1.) {\n return NAN;\n }\n return asin(x);\n",ds=Zi+"\n if (abs(x) > 1.) {\n return NAN;\n }\n return acos(x);\n",vs=Zi+"\n return atan(x);\n",ms=Zi+"return log(x + sqrt(x * x + 1.0));",gs=Zi+"\n if (x < 1.0) return NAN;\n return log(x + sqrt(x * x - 1.0));",ys=Zi+"\n if ((x < -1.0) || (x > 1.0)) return NAN;\n return (log(1.0 + x) - log(1.0 - x)) / 2.0;",xs="return x;",bs="return x;",ws="\n vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n bvec4 isNaN = isnan(x);\n\n result.r = isNaN.r ? x.r : result.r;\n result.g = isNaN.g ? x.g : result.g;\n result.b = isNaN.b ? x.b : result.b;\n result.a = isNaN.a ? x.a : result.a;\n\n return result;\n",Cs="\n vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));\n bvec4 isNaN = isnan(x);\n\n result.r = isNaN.r ? x.r : result.r;\n result.g = isNaN.g ? x.g : result.g;\n result.b = isNaN.b ? x.b : result.b;\n result.a = isNaN.a ? x.a : result.a;\n\n return result;\n",Es="\n vec4 result;\n\n result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n return result;\n",Rs=function(){return function(t,e){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t,this.userCode="\n vec4 unaryOperation(vec4 x) {\n "+e+"\n }\n\n void main() {\n vec4 x = getAAtOutCoords();\n vec4 y = unaryOperation(x);\n\n setOutput(y);\n }\n "}}(),Is=function(){return function(t){this.variableNames=["A"],this.usesPackedTextures=!0,this.outputShape=t;var e=t.length,n=Mo("rc",e),r=Xo(e),o=function(t,e){if(1===t)return"rc";for(var n="",r=0;r0?this.gpgpu.beginQuery():{startMs:H(),endMs:null}},t.prototype.endTimer=function(t){return a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(this.gpgpu.endQuery(),t):(t.endMs=H(),t)},t.prototype.getQueryTime=function(t){return n(this,void 0,void 0,function(){var e;return r(this,function(n){return a().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?[2,this.gpgpu.waitForQueryAndGetTime(t)]:[2,(e=t).endMs-e.startMs]})})},t.prototype.disposeData=function(t){if(!this.pendingDisposal.has(t))if(this.pendingRead.has(t))this.pendingDisposal.add(t);else if(this.texData.has(t)){this.releaseGPUData(t);var e=this.texData.get(t).complexTensors;null!=e&&(e.real.dispose(),e.imag.dispose()),this.texData.delete(t)}},t.prototype.releaseGPUData=function(t){var e=this.texData.get(t),n=e.texture,r=e.dtype,o=e.texShape,a=e.usage,i=e.isPacked,s=e.slice,u=s&&s.origDataId||t,l=this.dataRefCount.get(u);l>1?this.dataRefCount.set(u,l-1):(this.dataRefCount.delete(u),null!=n&&(this.numBytesInGPU-=this.computeBytes(o,r),this.textureManager.releaseTexture(n,o,a,i)));var c=this.texData.get(t);c.texture=null,c.texShape=null,c.isPacked=!1,c.slice=null},t.prototype.getTexture=function(t){return this.uploadToGPU(t),this.texData.get(t).texture},t.prototype.getDataInfo=function(t){return this.texData.get(t)},t.prototype.getCPUBackend=function(){return a().getBool("WEBGL_CPU_FORWARD")?(null==this.cpuBackend&&(this.cpuBackend=kt.findBackend("cpu")),this.cpuBackend):null},t.prototype.shouldExecuteOnCPU=function(t,e){var n=this;return void 0===e&&(e=128),null!=this.getCPUBackend()&&t.every(function(t){return null==n.texData.get(t.dataId).texture&&t.sizea().getNumber("WEBGL_MAX_TEXTURES_IN_SHADER")){var o=Math.floor(t.length/2),i=this.concat(t.slice(0,o),e),s=this.concat(t.slice(o),e);return this.concat([i,s],e)}if(a().getBool("WEBGL_PACK_ARRAY_OPERATIONS")&&t[0].rank>1){var u=new ga(t.map(function(t){return t.shape}),e);return this.compileAndRun(u,t)}var l=vn(t.map(function(t){return t.shape}),e),c=t.map(function(t){return t.as2D(-1,v(t.shape.slice(e)))}),h=new ma(c.map(function(t){return t.shape}));return this.compileAndRun(h,c).reshape(l)},t.prototype.neg=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.neg(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,is,t.dtype);var e=new Ji(t.shape,is);return this.compileAndRun(e,[t])},t.prototype.batchMatMul=function(t,e,n,r){var o=n?t.shape[2]:t.shape[1],a=r?e.shape[1]:e.shape[2],i=n?t.shape[1]:t.shape[2],s=t.shape[0];if((1===o||1===a)&&i>1e3){n&&(t=t.transpose([0,2,1])),r&&(e=e.transpose([0,2,1]));var u=1===a?t:t.as3D(s,i,1),l=1===a?2:1,c=1===a?e.as3D(s,1,i):e;return this.multiply(u,c).sum(l,!0)}var h=gt(t.dtype,e.dtype),p=new bi(t.shape,[s,o,a],n,r),f=this.makePackedTensor(p.outputShape,h);return this.compileAndRun(p,[t,e],f)},t.prototype.fusedBatchMatMul=function(t){var e=t.a,n=t.b,r=t.transposeA,o=t.transposeB,a=t.bias,i=t.activation,s=t.preluActivationWeights,u=r?e.shape[2]:e.shape[1],l=o?n.shape[1]:n.shape[2],c=e.shape[0],h=gt(e.dtype,n.dtype),p=null!=a,f=null!=s,d=i?Ns(i,!0):null,v=new bi(e.shape,[c,u,l],r,o,p,d,f),m=this.makePackedTensor(v.outputShape,h),g=[e,n];return a&&g.push(a),s&&g.push(s),this.compileAndRun(v,g,m)},t.prototype.multiply=function(t,e){if("complex64"===t.dtype){var n=this.texData.get(t.dataId),r=this.texData.get(e.dataId),o=new aa(ra,t.shape,e.shape),i=new aa(oa,t.shape,e.shape),s=[this.makeComplexComponentTensorHandle(t,n.complexTensors.real),this.makeComplexComponentTensorHandle(t,n.complexTensors.imag),this.makeComplexComponentTensorHandle(e,r.complexTensors.real),this.makeComplexComponentTensorHandle(e,r.complexTensors.imag)],u=this.compileAndRun(o,s),l=this.compileAndRun(i,s),c=this.complex(u,l);return u.dispose(),l.dispose(),c}if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.multiply(t,e);if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,ua,t.dtype);var h=new ca(ua,t.shape,e.shape),p=this.makeOutputArray(h.outputShape,t.dtype);return this.compileAndRun(h,[t,e],p)},t.prototype.batchNormalization=function(t,e,n,r,o,i){var s=[t,e,n],u=null;null!=i&&(u=i.shape,s.push(i));var l=null;if(null!=o&&(l=o.shape,s.push(o)),a().getBool("WEBGL_PACK_NORMALIZATION")){var c=new na(t.shape,e.shape,n.shape,u,l,r);return this.compileAndRun(c,s)}var h=new ea(t.shape,e.shape,n.shape,u,l,r);return this.compileAndRun(h,s)},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){var i=a().getBool("WEBGL_PACK_NORMALIZATION")?new gi(t.shape,e,n,r,o):new vi(t.shape,e,n,r,o);return this.compileAndRun(i,[t])},t.prototype.LRNGrad=function(t,e,n,r,o,a,i){var s=new mi(e.shape,r,o,a,i);return this.compileAndRun(s,[e,n,t])},t.prototype.tile=function(t,e){if("string"===t.dtype){var n=this.readSync(t.dataId).map(function(t){return K(t)});return So(tr(t.shape,t.dtype,n),e)}var r=new Ki(t.shape,e);return this.compileAndRun(r,[t])},t.prototype.pad=function(t,e,n){var r=a().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Ii(t.shape,e,n):new Ri(t.shape,e,n);return this.compileAndRun(r,[t])},t.prototype.transpose=function(t,e){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.transpose(t,e);var n=a().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Xi(t.shape,e):new ji(t.shape,e);return this.compileAndRun(n,[t])},t.prototype.gather=function(t,e,n){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.gather(t,e,n);var r=new $a(t.shape,e.size,n);return this.compileAndRun(r,[t,e])},t.prototype.batchToSpaceND=function(t,e,n){h(t.rank<=4,function(){return"batchToSpaceND for rank > 4 with a WebGL backend not implemented yet"});var r=e.reduce(function(t,e){return t*e}),o=Sr(t.shape,e,r),a=Ar(o.length,e.length),i=Tr(t.shape,e,r),s=Dr(n,e.length),u=_r(i,n,e.length);return t.reshape(o).transpose(a).reshape(i).slice(s,u)},t.prototype.spaceToBatchND=function(t,e,n){h(t.rank<=4,function(){return"spaceToBatchND for rank > 4 with a WebGL backend not implemented yet"});var r=e.reduce(function(t,e){return t*e}),o=[[0,0]];o.push.apply(o,n);for(var a=1+e.length;ae||n===t?r=!0:n=L(t,n+1);return n}(i,o),u=new Li({windowSize:s,inSize:i,batchSize:a,numSegments:o},e),l=u.outputShape,c=l[0],h=l[1],p=this.makeOutputArray([c,h],r);return this.compileAndRun(u,[t,n],p),p.shape[1]===o?p:(n=On(0,o).tile([i/s]),this.segOpCompute(p,e,n,r,o))},t.prototype.argMinMaxReduce=function(t,e,n){var r=[e];if(cn("arg"+n.charAt(0).toUpperCase()+n.slice(1),r,t.rank),!a().getBool("WEBGL_PACK_REDUCE")||t.rank<=2){var o=un(t.shape,r),i=o[0],s=v(o[1]),u=t.as2D(-1,s);return this.argReduce(u,n).reshape(i)}return this.argReducePacked(t,n)},t.prototype.argMin=function(t,e){return this.argMinMaxReduce(t,e,"min")},t.prototype.argMax=function(t,e){return this.argMinMaxReduce(t,e,"max")},t.prototype.cumsum=function(t,e,n,r){if(e!==t.rank-1)throw new Error("WebGL cumsum shader expects an inner-most axis="+(t.rank-1)+" but got axis="+e);var o=new Ta(t.shape,n,r);return this.compileAndRun(o,[t])},t.prototype.equal=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(equal(a, b));\n","bool");var n=new ca("return float(a == b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.notEqual=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(notEqual(a, b));\n","bool");var n=new ca("return float(a != b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.less=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.less(t,e);if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(lessThan(a, b));\n","bool");var n=new ca("return float(a < b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.lessEqual=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(lessThanEqual(a, b));\n","bool");var n=new ca("return float(a <= b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.greater=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.greater(t,e);if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(greaterThan(a, b));\n","bool");var n=new ca("return float(a > b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.greaterEqual=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(greaterThanEqual(a, b));\n","bool");var n=new ca("return float(a >= b);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.logicalNot=function(t){var e=new Ji(t.shape,"return float(!(x >= 1.0));");return this.compileAndRun(e,[t])},t.prototype.logicalAnd=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return vec4(\n vec4(greaterThanEqual(a, vec4(1.0))) *\n vec4(greaterThanEqual(b, vec4(1.0))));\n","bool");var n=new ca("return float(a >= 1.0 && b >= 1.0);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.logicalOr=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n return min(\n vec4(greaterThanEqual(a, vec4(1.0))) +\n vec4(greaterThanEqual(b, vec4(1.0))),\n vec4(1.0));\n","bool");var n=new ca("return float(a >= 1.0 || b >= 1.0);",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"bool");return this.compileAndRun(n,[t,e],r)},t.prototype.select=function(t,e,n){var r=new Wi(t.rank,e.shape,e.rank),o=this.makeOutputArray(r.outputShape,gt(e.dtype,n.dtype));return this.compileAndRun(r,[t,e,n],o)},t.prototype.where=function(t){tn("tf.where() in webgl locks the UI thread. Call tf.whereAsync() instead");var e=t.dataSync();return To(t.shape,e)},t.prototype.topk=function(t,e,n){return Ao(t.dataSync(),t.shape,t.dtype,e)},t.prototype.min=function(t,e){cn("min",e,t.rank);var n=un(t.shape,e),r=n[0],o=v(n[1]),a=t.as2D(-1,o);return this.reduce(a,"min",a.dtype).reshape(r)},t.prototype.minimum=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.minimum(t,e);var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("\n vec4 result = vec4(min(a, b));\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new ca("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return min(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.mod=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("\n vec4 result = mod(a, b);\n vec4 isNaN = vec4(equal(b, vec4(0.0)));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new ca("if (b == 0.0) return NAN;\n return mod(a, b);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.max=function(t,e){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.max(t,e);cn("max",e,t.rank);var n=un(t.shape,e),r=n[0],o=v(n[1]),a=t.as2D(-1,o);return this.reduce(a,"max",a.dtype).reshape(r)},t.prototype.maximum=function(t,e){if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.maximum(t,e);var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("\n vec4 result = vec4(max(a, b));\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new ca("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return max(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.all=function(t,e){cn("all",e,t.rank);var n=un(t.shape,e),r=n[0],o=v(n[1]),a=t.as2D(-1,o);return this.reduce(a,"all",a.dtype).reshape(r)},t.prototype.any=function(t,e){cn("any",e,t.rank);var n=un(t.shape,e),r=n[0],o=v(n[1]),a=t.as2D(-1,o);return this.reduce(a,"any",a.dtype).reshape(r)},t.prototype.squaredDifference=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("return (a - b) * (a - b);",t.shape,e.shape):new ca("return (a - b) * (a - b);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.realDivide=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS")){return this.packedBinaryOp(t,e,"\n // vec4 one = vec4(equal(a, b));\n // return one + (vec4(1.0) - one) * a / b;\n vec4 result = a / b;\n if(a.x == b.x) {\n result.x = 1.;\n }\n if(a.y == b.y) {\n result.y = 1.;\n }\n if(a.z == b.z) {\n result.z = 1.;\n }\n if(a.w == b.w) {\n result.w = 1.;\n }\n\n return result;\n","float32",!0)}var n=new ca("\nif (a == b) {\n return 1.0;\n};\nreturn a / b;",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"float32");return this.compileAndRun(n,[t,e],r)},t.prototype.floorDiv=function(t,e){if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,"\n ivec4 ia = round(a);\n ivec4 ib = round(b);\n bvec4 cond = notEqual(ib, ivec4(0));\n ivec4 result = ivec4(0);\n vec4 s = sign(a) * sign(b);\n\n // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n if (cond[0]) {\n result[0] = idiv(ia[0], ib[0], s[0]);\n }\n if (cond[1]) {\n result[1] = idiv(ia[1], ib[1], s[1]);\n }\n if (cond[2]) {\n result[2] = idiv(ia[2], ib[2], s[2]);\n }\n if (cond[3]) {\n result[3] = idiv(ia[3], ib[3], s[3]);\n }\n return vec4(result);\n","int32");var n=new ca("\n float s = sign(a) * sign(b);\n int ia = round(a);\n int ib = round(b);\n if (ib != 0) {\n // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n return float(idiv(ia, ib, s));\n } else {\n return NAN;\n }\n",t.shape,e.shape),r=this.makeOutputArray(n.outputShape,"int32");return this.compileAndRun(n,[t,e],r)},t.prototype.add=function(t,e){if("complex64"===t.dtype&&"complex64"===e.dtype)return this.complexSeparableBinaryOp(t,e,ia);if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.add(t,e);var n=gt(t.dtype,e.dtype);if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,ia,n);var r=new ca(ia,t.shape,e.shape),o=this.makeOutputArray(r.outputShape,n);return this.compileAndRun(r,[t,e],o)},t.prototype.packedUnaryOp=function(t,e,n){var r=new Rs(t.shape,e),o=this.makePackedTensor(r.outputShape,n);return this.compileAndRun(r,[t],o)},t.prototype.packedBinaryOp=function(t,e,n,r,o){void 0===o&&(o=!1);var a=new pa(n,t.shape,e.shape,o),i=this.makePackedTensor(a.outputShape,r);return this.compileAndRun(a,[t,e],i)},t.prototype.complexSeparableBinaryOp=function(t,e,n){var r=this,o=this.texData.get(t.dataId),a=this.texData.get(e.dataId),i=[[o.complexTensors.real,a.complexTensors.real],[o.complexTensors.imag,a.complexTensors.imag]].map(function(o){var a=o[0],i=o[1],s=r.makeComplexComponentTensorHandle(t,a),u=r.makeComplexComponentTensorHandle(e,i),l=new ca(n,t.shape,e.shape),c=r.makeOutputArray(l.outputShape,gt(a.dtype,i.dtype));return r.compileAndRun(l,[s,u],c)}),s=i[0],u=i[1],l=this.complex(s,u);return s.dispose(),u.dispose(),l},t.prototype.makeComplexComponentTensorHandle=function(t,e){return{dataId:e.dataId,dtype:e.dtype,shape:t.shape}},t.prototype.addN=function(t){if(1===t.length)return t[0];if(t.length>a().get("WEBGL_MAX_TEXTURES_IN_SHADER")){var e=Math.floor(t.length/2),n=this.addN(t.slice(0,e)),r=this.addN(t.slice(e));return this.addN([n,r])}var o=t.map(function(t){return t.dtype}).reduce(function(t,e){return gt(t,e)}),i=t.map(function(t){return t.shape}),s=a().getBool("WEBGL_PACK"),u=s?new _o(t[0].shape,i):new Do(t[0].shape,i),l=s?this.makePackedTensor(u.outputShape,o):this.makeOutputArray(u.outputShape,o);return this.compileAndRun(u,t,l)},t.prototype.subtract=function(t,e){if("complex64"===t.dtype&&"complex64"===e.dtype)return this.complexSeparableBinaryOp(t,e,sa);if(this.shouldExecuteOnCPU([t,e]))return this.cpuBackend.subtract(t,e);var n=gt(t.dtype,e.dtype);if(a().getBool("WEBGL_PACK_BINARY_OPERATIONS"))return this.packedBinaryOp(t,e,sa,t.dtype);var r=new ca(sa,t.shape,e.shape),o=this.makeOutputArray(r.outputShape,n);return this.compileAndRun(r,[t,e],o)},t.prototype.pow=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS"),r=n?new pa("\n // isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise.\n vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1)));\n vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1);\n vec4 result = multiplier * pow(abs(a), b);\n\n // Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS\n bvec4 isExpZero = equal(b, vec4(0.0));\n result.r = isExpZero.r ? 1.0 : result.r;\n result.g = isExpZero.g ? 1.0 : result.g;\n result.b = isExpZero.b ? 1.0 : result.b;\n result.a = isExpZero.a ? 1.0 : result.a;\n\n vec4 isNaN = vec4(lessThan(a, vec4(0.0))) * vec4(lessThan(floor(b), b));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new ca("\nif(a < 0.0 && floor(b) < b){\n return NAN;\n}\nif (b == 0.0) {\n return 1.0;\n}\nreturn (round(mod(b, 2.0)) != 1) ?\n pow(abs(a), b) : sign(a) * pow(abs(a), b);\n",t.shape,e.shape),o=gt(t.dtype,e.dtype),i=n?this.makePackedTensor(r.outputShape,o):this.makeOutputArray(r.outputShape,o);return this.compileAndRun(r,[t,e],i)},t.prototype.ceil=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.ceil(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,ss,t.dtype);var e=new Ji(t.shape,ss);return this.compileAndRun(e,[t])},t.prototype.floor=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.floor(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,us,t.dtype);var e=new Ji(t.shape,us);return this.compileAndRun(e,[t])},t.prototype.sign=function(t){var e=new Ji(t.shape,"\n if (isnan(x)) { return 0.0; }\n return sign(x);\n");return this.compileAndRun(e,[t])},t.prototype.isNaN=function(t){var e=new Ji(t.shape,"return float(isnan(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.isInf=function(t){var e=new Ji(t.shape,"return float(isinf(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.isFinite=function(t){var e=new Ji(t.shape,"return float(!isnan(x) && !isinf(x));"),n=this.makeOutputArray(e.outputShape,"bool");return this.compileAndRun(e,[t],n)},t.prototype.round=function(t){var e=new Ji(t.shape,"\n // OpenGL ES does not support round function.\n // The algorithm is based on banker's rounding.\n float base = floor(x);\n if ((x - base) < 0.5) {\n return floor(x);\n } else if ((x - base) > 0.5) {\n return ceil(x);\n } else {\n if (mod(base, 2.0) == 0.0) {\n return base;\n } else {\n return base + 1.0;\n }\n }\n");return this.compileAndRun(e,[t])},t.prototype.exp=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.exp(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,ls,t.dtype);var e=new Ji(t.shape,ls);return this.compileAndRun(e,[t])},t.prototype.expm1=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.expm1(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,cs,t.dtype);var e=new Ji(t.shape,cs);return this.compileAndRun(e,[t])},t.prototype.log=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.log(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,"\n vec4 result = log(x);\n vec4 isNaN = vec4(lessThan(x, vec4(0.0)));\n result.r = isNaN.r == 1.0 ? NAN : result.r;\n result.g = isNaN.g == 1.0 ? NAN : result.g;\n result.b = isNaN.b == 1.0 ? NAN : result.b;\n result.a = isNaN.a == 1.0 ? NAN : result.a;\n\n return result;\n",t.dtype);var e=new Ji(t.shape,"if (x < 0.0) return NAN;\n return log(x);");return this.compileAndRun(e,[t])},t.prototype.log1p=function(t){var e=new Ji(t.shape,"return log(1.0 + x);");return this.compileAndRun(e,[t])},t.prototype.sqrt=function(t){var e=new Ji(t.shape,"return sqrt(x);");return this.compileAndRun(e,[t])},t.prototype.rsqrt=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.rsqrt(t);var e=new Ji(t.shape,"return inversesqrt(x);");return this.compileAndRun(e,[t])},t.prototype.square=function(t){var e=new Ji(t.shape,"return x * x;");return this.compileAndRun(e,[t])},t.prototype.reciprocal=function(t){var e=new Ji(t.shape,"return 1.0 / x;");return this.compileAndRun(e,[t])},t.prototype.relu=function(t){var e;return e=a().getBool("WEBGL_PACK")?new Rs(t.shape,ws):new Ji(t.shape,ns),this.compileAndRun(e,[t])},t.prototype.relu6=function(t){var e;return e=a().getBool("WEBGL_PACK")?new Rs(t.shape,Cs):new Ji(t.shape,rs),this.compileAndRun(e,[t])},t.prototype.prelu=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa(ha,t.shape,e.shape):new ca(la,t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.elu=function(t){if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,Es,t.dtype);var e=new Ji(t.shape,os);return this.compileAndRun(e,[t])},t.prototype.eluDer=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("\n vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));\n return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));\n",t.shape,e.shape):new ca("return (b >= 1.0) ? a : a * (b + 1.0);",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.selu=function(t){var e=new Ji(t.shape,as);return this.compileAndRun(e,[t])},t.prototype.int=function(t){var e=new Ji(t.shape,"return float(int(x));"),n=this.makeOutputArray(e.outputShape,"int32");return this.compileAndRun(e,[t],n)},t.prototype.clip=function(t,e,n){var r,o=(r=a().getBool("WEBGL_PACK_CLIP")?new da(t.shape):new fa(t.shape)).getCustomSetupFunc(e,n);return this.compileAndRun(r,[t],null,o)},t.prototype.abs=function(t){if(this.shouldExecuteOnCPU([t]))return this.cpuBackend.abs(t);if(a().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(t,es,t.dtype);var e=new Ji(t.shape,es);return this.compileAndRun(e,[t])},t.prototype.complexAbs=function(t){var e=this.texData.get(t.dataId),n=new va(t.shape),r=[this.makeComplexComponentTensorHandle(t,e.complexTensors.real),this.makeComplexComponentTensorHandle(t,e.complexTensors.imag)];return this.compileAndRun(n,r)},t.prototype.sigmoid=function(t){var e=new Ji(t.shape,"return 1.0 / (1.0 + exp(-1.0 * x));");return this.compileAndRun(e,[t])},t.prototype.softplus=function(t){var e=new Ji(t.shape,"\n float epsilon = 1.1920928955078125e-7;\n float threshold = log(epsilon) + 2.0;\n\n bool too_large = x > -threshold;\n bool too_small = x < threshold;\n\n float result;\n float exp_x = exp(x);\n\n if (too_large){\n result = x;\n }\n else if (too_small){\n result = exp_x;\n }\n else{\n result = log(exp_x + 1.0);\n }\n return result;\n");return this.compileAndRun(e,[t])},t.prototype.sin=function(t){var e=new Ji(t.shape,hs);return this.compileAndRun(e,[t])},t.prototype.cos=function(t){var e=new Ji(t.shape,ps);return this.compileAndRun(e,[t])},t.prototype.tan=function(t){var e=new Ji(t.shape,"return tan(x);");return this.compileAndRun(e,[t])},t.prototype.asin=function(t){var e=new Ji(t.shape,fs);return this.compileAndRun(e,[t])},t.prototype.acos=function(t){var e=new Ji(t.shape,ds);return this.compileAndRun(e,[t])},t.prototype.atan=function(t){var e=new Ji(t.shape,vs);return this.compileAndRun(e,[t])},t.prototype.atan2=function(t,e){var n=a().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new pa("\n vec4 result = atan(a, b);\n vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n \n result.r = isNaN.r > 0. ? NAN : result.r;\n result.g = isNaN.g > 0. ? NAN : result.g;\n result.b = isNaN.b > 0. ? NAN : result.b;\n result.a = isNaN.a > 0. ? NAN : result.a;\n\n return result;\n",t.shape,e.shape):new ca("\n if (isnan(a)) return a;\n if (isnan(b)) return b;\n\n return atan(a, b);\n",t.shape,e.shape);return this.compileAndRun(n,[t,e])},t.prototype.sinh=function(t){var e=new Ji(t.shape,"\n float e2x = exp(x);\n return (e2x - 1.0 / e2x) / 2.0;\n");return this.compileAndRun(e,[t])},t.prototype.cosh=function(t){var e=new Ji(t.shape,"\n float e2x = exp(-x);\n return (e2x + 1.0 / e2x) / 2.0;\n");return this.compileAndRun(e,[t])},t.prototype.tanh=function(t){var e=new Ji(t.shape,"\n float e2x = exp(-2.0 * abs(x));\n return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n");return this.compileAndRun(e,[t])},t.prototype.asinh=function(t){var e=new Ji(t.shape,ms);return this.compileAndRun(e,[t])},t.prototype.acosh=function(t){var e=new Ji(t.shape,gs);return this.compileAndRun(e,[t])},t.prototype.atanh=function(t){var e=new Ji(t.shape,ys);return this.compileAndRun(e,[t])},t.prototype.erf=function(t){var e=new Ji(t.shape,'\n // Error function is calculated approximately with elementary function.\n // See "Handbook of Mathematical Functions with Formulas,\n // Graphs, and Mathematical Tables", Abramowitz and Stegun.\n float p = 0.3275911;\n float a1 = 0.254829592;\n float a2 = -0.284496736;\n float a3 = 1.421413741;\n float a4 = -1.453152027;\n float a5 = 1.061405429;\n\n float sign = sign(x);\n x = abs(x);\n float t = 1.0 / (1.0 + p * x);\n return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x));\n');return this.compileAndRun(e,[t])},t.prototype.step=function(t,e){var n=new Ji(t.shape,function(t){return void 0===t&&(t=0),Zi+"\n return x > 0.0 ? 1.0 : float("+t+");\n "}(e));return this.compileAndRun(n,[t])},t.prototype.conv2dByMatMul=function(t,e,n,r,o,i){var s=t.shape,u=this.texData.get(t.dataId),l=n.inChannels,c=s[0]*s[1]*s[2],p=n.outChannels,f="channelsLast"===n.dataFormat,d=(1===c||1===p)&&l>1e3,v=s[2]%2!=0&&!!u.isPacked;if(d||!a().getBool("WEBGL_LAZILY_UNPACK")||!a().getBool("WEBGL_PACK_BINARY_OPERATIONS")||!v){var m=f?s[0]*s[1]*s[2]:s[0]*s[2]*s[3],g=this.reshape(t,[1,m,n.inChannels]),y=this.reshape(e,[1,n.inChannels,n.outChannels]);return this.reshape(this.fusedBatchMatMul({a:g,b:y,transposeA:!1,transposeB:!1,bias:r,activation:o,preluActivationWeights:i}),n.outShape)}var x=f?s[0]*s[1]*(s[2]+1):s[0]*s[2]*(s[3]+1),b=ut.make([1,x,n.inChannels],{dataId:t.dataId},t.dtype,this),w=u.shape;u.shape=u.shape.slice(),u.shape[u.shape.length-2]++,h(we(u.shape,b.shape),function(){return"packed reshape "+u.shape+" to "+b.shape+" isn't free"});var C=this.reshape(e,[1,n.inChannels,n.outChannels]),E=this.fusedBatchMatMul({a:b,b:C,transposeA:!1,transposeB:!1,bias:r,activation:o,preluActivationWeights:i}),R=this.texData.get(E.dataId);return h(R.isPacked,function(){return"batchMatMul result is expected to be packed"}),u.shape=w,R.shape=n.outShape,ut.make(n.outShape,{dataId:E.dataId},E.dtype,this)},t.prototype.conv2dWithIm2Row=function(t,e,n,r,o,a){var i=n.filterWidth,s=n.filterHeight,u=n.inChannels,l=n.outWidth,c=n.outHeight,h="channelsLast"===n.dataFormat,p=i*s*u,f=c*l,d=[p,f],v=t.squeeze([0]),m=e.reshape([1,p,-1]),g=new di(d,v.shape,n),y=this.compileAndRun(g,[v]).reshape([1,d[0],d[1]]),x=null!=r,b=null!=a,w=o?Ns(o,!0):null,C=new bi(y.shape,[1,f,n.outChannels],!0,!1,x,w,b),E=[y,m];r&&E.push(r),b&&E.push(a);var R=this.compileAndRun(C,E);return h?R.reshape([1,c,l,n.outChannels]):R.reshape([1,n.outChannels,c,l])},t.prototype.fusedConv2d=function(t){var e=t.input,n=t.filter,r=t.convInfo,o=t.bias,i=t.activation,s=t.preluActivationWeights;if(1===r.filterHeight&&1===r.filterWidth&&1===r.dilationHeight&&1===r.dilationWidth&&1===r.strideHeight&&1===r.strideWidth&&("SAME"===r.padInfo.type||"VALID"===r.padInfo.type))return this.conv2dByMatMul(e,n,r,o,i,s);if(a().getBool("WEBGL_CONV_IM2COL")&&1===e.shape[0])return this.conv2dWithIm2Row(e,n,r,o,i,s);var u=null!=o,l=null!=s,c=i?Ns(i,!1):null,h=new Ia(r,u,c,l),p=[e,n];return o&&p.push(o),s&&p.push(s),this.compileAndRun(h,p)},t.prototype.conv2d=function(t,e,n){if(1===n.filterHeight&&1===n.filterWidth&&1===n.dilationHeight&&1===n.dilationWidth&&1===n.strideHeight&&1===n.strideWidth&&("SAME"===n.padInfo.type||"VALID"===n.padInfo.type))return this.conv2dByMatMul(t,e,n);if(a().getBool("WEBGL_CONV_IM2COL")&&1===t.shape[0])return this.conv2dWithIm2Row(t,e,n);var r=new Ia(n);return this.compileAndRun(r,[t,e])},t.prototype.conv2dDerInput=function(t,e,n){var r=new ba(n);return this.compileAndRun(r,[t,e])},t.prototype.conv2dDerFilter=function(t,e,n){var r=new xa(n);return this.compileAndRun(r,[t,e])},t.prototype.fusedDepthwiseConv2D=function(t){var e,n=t.input,r=t.filter,o=t.convInfo,i=t.bias,s=t.activation,u=t.preluActivationWeights,l=a().getBool("WEBGL_PACK_DEPTHWISECONV")&&o.strideWidth<=2&&o.outChannels/o.inChannels==1,c=s?Ns(s,l):null,h=[n,r],p=null!=i,f=null!=u;return p&&h.push(i),f&&h.push(u),l?(e=new Sa(o,p,c,f),this.compileAndRun(e,h,this.makePackedTensor(o.outShape,n.dtype))):(e=new Na(o,p,c,f),this.compileAndRun(e,h))},t.prototype.depthwiseConv2D=function(t,e,n){var r;return a().getBool("WEBGL_PACK_DEPTHWISECONV")&&n.strideWidth<=2&&n.outChannels/n.inChannels==1?(r=new Sa(n),this.compileAndRun(r,[t,e],this.makePackedTensor(n.outShape,t.dtype))):(r=new Na(n),this.compileAndRun(r,[t,e]))},t.prototype.depthwiseConv2DDerInput=function(t,e,n){var r=new Ra(n);return this.compileAndRun(r,[t,e])},t.prototype.depthwiseConv2DDerFilter=function(t,e,n){var r=new Ea(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3d=function(t,e,n){var r=new ka(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3dDerInput=function(t,e,n){var r=new Ca(n);return this.compileAndRun(r,[t,e])},t.prototype.conv3dDerFilter=function(t,e,n){var r=new wa(n);return this.compileAndRun(r,[t,e])},t.prototype.maxPool=function(t,e){var n=new ki(e,"max",!1),r=this.makeOutputArray(n.outputShape,t.dtype);return this.compileAndRun(n,[t],r)},t.prototype.avgPool=function(t,e){var n=new ki(e,"avg",!1),r=this.makeOutputArray(n.outputShape,"float32");return this.compileAndRun(n,[t],r)},t.prototype.maxPoolBackprop=function(t,e,n,r){var o=new ki(r,"max",!0),a=this.compileAndRun(o,[e]),i=new yi(r),s=this.makeOutputArray(i.outputShape,e.dtype),u=this.compileAndRun(i,[t,a],s);return a.dispose(),u},t.prototype.avgPoolBackprop=function(t,e,n){var r=new Zo(n),o=this.makeOutputArray(r.outputShape,e.dtype);return this.compileAndRun(r,[t],o)},t.prototype.cast=function(t,e){return go(t,e,this)},t.prototype.unstack=function(t,e){for(var n=t.shape[e],r=new Array(t.rank-1),o=0,a=0;a1,function(){return"blockSize should be > 1 for depthToSpace, but was: "+e});var r=t.shape[0],o="NHWC"===n?t.shape[1]:t.shape[2],a="NHWC"===n?t.shape[2]:t.shape[3],i="NHWC"===n?t.shape[3]:t.shape[1],s=o*e,u=a*e,l=i/(e*e),c=new Fa("NHWC"===n?[r,s,u,l]:[r,l,s,u],e,n);return this.compileAndRun(c,[t])},t.prototype.split=function(t,e,n){return No(t,e,n)},t.prototype.scatterND=function(t,e,n){var r=Pr(0,t,n),o=r.sliceRank,a=r.numUpdates,i=r.sliceSize,s=r.strides,u=r.outputSize,l=[u/i,i],c=t.reshape([a,o]),h=e.reshape([a,i]);if(0===u)return yo(bn([]),n);var p=Cn(0),f=new Pi(a,o,c.rank,h.rank,s,l);return this.compileAndRun(f,[h,c,p]).reshape(n)},t.prototype.sparseToDense=function(t,e,n,r){var o=Pr(0,t,n),a=o.sliceRank,i=o.numUpdates,s=o.strides,u=o.outputSize,l=new Pi(i,a,t.rank,e.rank,s,[u,1],!1);return this.compileAndRun(l,[e,t,r]).reshape(n)},t.prototype.fft=function(t){return this.fftImpl(t,!1)},t.prototype.ifft=function(t){return this.fftImpl(t,!0)},t.prototype.fftImpl=function(t,e){var n=this.texData.get(t.dataId),r=new za(Ua,t.shape,e),o=new za(Va,t.shape,e),a=[this.makeComplexComponentTensorHandle(t,n.complexTensors.real),this.makeComplexComponentTensorHandle(t,n.complexTensors.imag)],i=this.compileAndRun(r,a),s=this.compileAndRun(o,a),u=this.complex(i,s).as2D(t.shape[0],t.shape[1]);return i.dispose(),s.dispose(),u},t.prototype.gatherND=function(t,e){var n=e.shape,r=n[n.length-1],o=Or(t,e),a=o[0],i=o[1],s=o[2],u=o[3],l=e.reshape([i,r]),c=t.reshape([t.size/s,s]),h=new Ka(r,u,[i,s]);return this.compileAndRun(h,[c,l]).reshape(a)},t.prototype.fill=function(t,e,n){if("string"===(n=n||B(e))){var r=k(n,v(t));return r.fill(e),ut.make(t,{values:r},n)}var o=new Ga(t,e),a=o.getCustomSetupFunc(e),i=this.makeOutputArray(t,n);return this.compileAndRun(o,[],i,a)},t.prototype.onesLike=function(t){if("string"===t.dtype)throw new Error("onesLike is not supported under string dtype");return this.fill(t.shape,1,t.dtype)},t.prototype.zerosLike=function(t){return this.fill(t.shape,"string"===t.dtype?"":0,t.dtype)},t.prototype.linspace=function(t,e,n){return xo(t,e,n)},t.prototype.makeOutputArray=function(t,e){return ut.make(t,{},e,this)},t.prototype.makePackedTensor=function(t,e){var n=ut.make(t,{},e,this);return this.texData.get(n.dataId).isPacked=!0,n},t.prototype.unpackTensor=function(t){var e=new Is(t.shape);return this.compileAndRun(e,[t],ut.make(e.outputShape,{},t.dtype,this))},t.prototype.packTensor=function(t){var e=new Ei(t.shape);return this.compileAndRun(e,[t],this.makePackedTensor(t.shape,t.dtype),null,!0)},t.prototype.packedReshape=function(t,e){var n=t.reshape([me(t.shape)].concat(ge(t.shape))),r=[me(e)].concat(ge(e)),o=new Ai(r,n.shape);return this.compileAndRun(o,[n],null,null,!0).reshape(e)},t.prototype.decode=function(t){var e,n=this.texData.get(t),r=n.isPacked,o=n.shape,a=n.dtype,i=ye(o),s=Pt(o),u=this.makeTensorHandle(o,"float32");return this.texData.get(u.dataId).isPacked=!0,this.texData.get(u.dataId).dtype=a,this.texData.get(u.dataId).texShape=s.map(function(t){return 2*t}),e=r?new Oa(i,s):new _a(i,s),this.compileAndRun(e,[{shape:i,dtype:a,dataId:t}],u,null,!0),u},t.prototype.compileAndRun=function(t,e,n,r,o){var i=this;if(void 0===o&&(o=!1),null==n&&(n=t.usesPackedTextures?this.makePackedTensor(t.outputShape,e[0].dtype):this.makeOutputArray(t.outputShape,e[0].dtype)),0===n.size)return this.texData.get(n.dataId).values=I(n.dtype,0),n;var s=e.map(function(e){if("complex64"===e.dtype)throw new Error("GPGPUProgram does not support complex64 input. For complex64 dtypes, please separate the program into real and imaginary parts.");var n=i.texData.get(e.dataId);if(null==n.texture){if(!t.usesPackedTextures&&v(e.shape)<=a().getNumber("WEBGL_SIZE_UPLOAD_UNIFORM"))return{shape:e.shape,texData:null,isUniform:!0,uniformValues:n.values};t.usesPackedTextures&&(n.isPacked=!0,n.shape=e.shape)}else if(!!n.isPacked!=!!t.usesPackedTextures)e=n.isPacked?i.unpackTensor(e):i.packTensor(e),n=i.texData.get(e.dataId);else if(n.isPacked&&!we(n.shape,e.shape)){var r=e,o=e.shape;e.shape=n.shape,e=i.packedReshape(e,o),n=i.texData.get(e.dataId),r.shape=o}return i.uploadToGPU(e.dataId),{shape:e.shape,texData:n,isUniform:!1}});this.uploadToGPU(n.dataId);var u,l={shape:n.shape,texData:this.texData.get(n.dataId),isUniform:!1},c=function(t,e,n){var r="";e.concat(n).forEach(function(t){var e=null!=t.texData&&null!=t.texData.slice&&t.texData.slice.flatOffset>0,n=t.isUniform?"uniform":t.texData.texShape;r+=t.shape+"_"+n+"_"+e});var o=t.userCode,a=t.constructor.name;return a+="_"+r+"_"+o}(t,s,l),h=this.getAndSaveBinary(c,function(){return function(t,e,n,r){var o=e.userCode,i=n.map(function(t,n){var r={logicalShape:t.shape,texShape:t.isUniform?null:t.texData.texShape,isUniform:t.isUniform,isPacked:!t.isUniform&&t.texData.isPacked,flatOffset:null};return null!=t.texData&&null!=t.texData.slice&&t.texData.slice.flatOffset>0&&(r.flatOffset=t.texData.slice.flatOffset),{name:e.variableNames[n],shapeInfo:r}}),s=i.map(function(t){return t.shapeInfo}),u={logicalShape:r.shape,texShape:r.texData.texShape,isUniform:!1,isPacked:r.texData.isPacked,flatOffset:null},l=Uo(i,u,o,e.usesPackedTextures),c=t.createProgram(l),h=null,p=t.getUniformLocation(c,"NAN",!1);1===a().getNumber("WEBGL_VERSION")&&(h=t.getUniformLocation(c,"INFINITY",!1));for(var f={},d=0;d0)return 32}return 16})),this.floatPrecisionValue},t.prototype.epsilon=function(){return 32===this.floatPrecision()?1e-7:1e-4},t.prototype.uploadToGPU=function(t){var e,n=this.texData.get(t),r=n.shape,o=n.dtype,a=n.values,i=n.texture,s=n.usage,u=n.isPacked;if(null==i){var l,c=null!=this.activeTimers;c&&(l=H());var h=n.texShape;if(null==h&&(h=xe(r,u),n.texShape=h),null!=a){var p=ye(r),f=void 0,d=h[1],m=h[0],g=a instanceof Uint8Array;u?(d=(e=Lt(h[0],h[1]))[0],m=e[1],f=new Wa(p,[m,d],g)):f=new La(p,[m,d],g);var y=this.makeTensorHandle([m,d],o);this.texData.get(y.dataId).usage=g?At.PIXELS:At.UPLOAD,this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(y.dataId),d,m,a);var x=this.makeTensorHandle(f.outputShape,y.dtype);x.size=v(f.outputShape),this.texData.get(x.dataId).isPacked=u,this.compileAndRun(f,[y],x);var b=this.texData.get(x.dataId);n.texture=b.texture,n.texShape=b.texShape,n.isPacked=b.isPacked,n.usage=b.usage,this.disposeData(y.dataId),this.texData.delete(x.dataId),n.values=null,c&&(this.uploadWaitMs+=H()-l)}else{var w=this.acquireTexture(h,s,o,u);n.texture=w}}},t.prototype.convertAndCacheOnCPU=function(t,e){var n=this.texData.get(t),r=n.dtype;return this.releaseGPUData(t),null!=e&&(n.values=function(t,e){if("float32"===e||"complex64"===e)return t;if("int32"===e||"bool"===e){for(var n="int32"===e?new Int32Array(t.length):new Uint8Array(t.length),r=0;r1024*this.numMBBeforeWarning*1024){var o=(this.numBytesInGPU/1024/1024).toFixed(2);this.warnedAboutMemory=!0,console.warn("High memory usage in GPU: "+o+" MB, most likely due to a memory leak")}return this.textureManager.acquireTexture(t,e,r)},t.prototype.computeBytes=function(t,e){return t[0]*t[1]*D(e)},t}();Nt()&&kt.registerBackend("webgl",function(){return new As},2);var Ts=mn({abs_:function(t){var e=rn(t,"x","abs");return"complex64"===e.dtype?kt.runKernel(function(t){return t.complexAbs(e)},{$x:e}):kt.runKernel(function(t,n){var r=t.abs(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.toFloat().step(-1))}}})}}),Ds=mn({acos_:function(t){var e=rn(t,"x","acos");return kt.runKernel(function(t,n){var r=t.acos(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.divStrict(Cn(1).sub(n.toFloat().square()).sqrt()).neg()}}})}}),_s=mn({acosh_:function(t){var e=rn(t,"x","acosh");return kt.runKernel(function(t,n){var r=t.acosh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.divStrict(n.toFloat().square().sub(1).sqrt())}}})}}),Os=mn({asin_:function(t){var e=rn(t,"x","asin");return kt.runKernel(function(t,n){var r=t.asin(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.divStrict(Cn(1).sub(n.toFloat().square()).sqrt())}}})}}),Fs=mn({asinh_:function(t){var e=rn(t,"x","asinh");return kt.runKernel(function(t,n){var r=t.asinh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.divStrict(Cn(1).add(n.toFloat().square()).sqrt())}}})}}),Ms=mn({atan_:function(t){var e=rn(t,"x","atan");return kt.runKernel(function(t,n){var r=t.atan(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.toFloat().square().add(1))}}})}}),Bs=mn({atanh_:function(t){var e=rn(t,"x","atanh");return kt.runKernel(function(t,n){var r=t.atanh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(Cn(1).sub(n.toFloat().square()))}}})}}),Ps=mn({ceil_:function(t){var e=rn(t,"x","ceil");return kt.runKernel(function(t){return t.ceil(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),Ls=mn({clipByValue_:function(t,e,n){var r=rn(t,"x","clipByValue");return h(e<=n,function(){return"Error in clip: min ("+e+") must be less than or equal to max ("+n+")."}),kt.runKernel(function(t,o){var a=t.clip(r,e,n);return o([r]),a},{$x:r},function(t,r){var o=r[0];return{$x:function(){return t.where(o.greaterEqual(e).logicalAnd(o.lessEqual(n)),Mn(t))}}})}}),Ws=mn({cos_:function(t){var e=rn(t,"x","cos");return kt.runKernel(function(t,n){var r=t.cos(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return n.toFloat().sin().neg().mul(t)}}})}}),Us=mn({cosh_:function(t){var e=rn(t,"x","cosh");return kt.runKernel(function(t,n){var r=t.cosh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return n.toFloat().sinh().mulStrict(t)}}})}}),Vs=mn({erf_:function(t){var e=rn(t,"x","erf");return h("int32"===e.dtype||"float32"===e.dtype,function(){return"Input dtype must be `int32` or `float32`."}),"int32"===e.dtype&&(e=e.toFloat()),kt.runKernel(function(t,n){var r=t.erf(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.square().neg().exp().mul(2/Math.sqrt(Math.PI)))}}})}}),zs=mn({exp_:function(t){var e=rn(t,"x","exp");return kt.runKernel(function(t,n){var r=t.exp(e);return n([r]),r},{$x:e},function(t,e){return{$x:function(){return t.mulStrict(e[0])}}})}}),Gs=mn({expm1_:function(t){var e=rn(t,"x","expm1");return kt.runKernel(function(t,n){var r=t.expm1(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.exp())}}})}}),Hs=mn({floor_:function(t){var e=rn(t,"x","floor");return kt.runKernel(function(t){return t.floor(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),qs=mn({log_:function(t){var e=rn(t,"x","log");return kt.runKernel(function(t,n){var r=t.log(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.toFloat())}}})}}),$s=mn({log1p_:function(t){var e=rn(t,"x","log1p");return kt.runKernel(function(t,n){var r=t.log1p(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.add(1))}}})}}),Ks=mn({logSigmoid_:function(t){var e=rn(t,"x","logSigmoid");return kt.runKernel(function(t,n){var r=t.softplus(e.neg()).neg();return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.neg().sigmoid())}}})}}),js=mn({neg_:function(t){var e=rn(t,"x","neg");return kt.runKernel(function(t){return t.neg(e)},{$x:e},function(t){return{$x:function(){return t.neg()}}})}}),Xs=mn({reciprocal_:function(t){var e=rn(t,"x","reciprocal");return kt.runKernel(function(t,n){var r=t.reciprocal(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.square().neg())}}})}}),Ys=mn({round_:function(t){var e=rn(t,"x","round");return kt.runKernel(function(t){return t.round(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),Qs=mn({rsqrt_:function(t){var e=rn(t,"x","rsqrt");return kt.runKernel(function(t,n){var r=t.rsqrt(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.pow(1.5).mul(2)).neg()}}})}}),Js=mn({sigmoid_:function(t){var e=rn(t,"x","sigmoid");return kt.runKernel(function(t,n){var r=t.sigmoid(e);return n([r]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.mul(Cn(1).sub(n)))}}})}}),Zs=mn({sign_:function(t){var e=rn(t,"x","sign");return kt.runKernel(function(t){return t.sign(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),tu=mn({isNaN_:function(t){var e=rn(t,"x","isNaN");return kt.runKernel(function(t){return t.isNaN(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),eu=mn({isInf_:function(t){var e=rn(t,"x","isInf");return kt.runKernel(function(t){return t.isInf(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),nu=mn({isFinite_:function(t){var e=rn(t,"x","isFinite");return kt.runKernel(function(t){return t.isFinite(e)},{$x:e},function(t){return{$x:function(){return Mn(t)}}})}}),ru=mn({sin_:function(t){var e=rn(t,"x","sin");return kt.runKernel(function(t,n){var r=t.sin(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return n.toFloat().cos().mul(t)}}})}}),ou=mn({sinh_:function(t){var e=rn(t,"x","sinh");return kt.runKernel(function(t,n){var r=t.sinh(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return n.toFloat().cosh().mulStrict(t)}}})}}),au=mn({softplus_:function(t){var e=rn(t,"x","softplus");return kt.runKernel(function(t,n){var r=t.softplus(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.sigmoid())}}})}}),iu=mn({sqrt_:function(t){var e=rn(t,"x","sqrt");return kt.runKernel(function(t,n){var r=t.sqrt(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.toFloat().sqrt().mul(2))}}})}}),su=mn({square_:function(t){var e=rn(t,"x","square");return kt.runKernel(function(t,n){return n([e]),t.square(e)},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mul(n.toFloat().mul(2))}}})}}),uu=mn({step_:function(t,e){void 0===e&&(e=0);var n=rn(t,"x","step");return kt.runKernel(function(t){return t.step(n,e)},{$x:n},function(t){return{$x:function(){return Mn(t)}}})}}),lu=mn({tan_:function(t){var e=rn(t,"x","tan");return kt.runKernel(function(t,n){var r=t.tan(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.div(n.cos().square())}}})}}),cu=mn({tanh_:function(t){var e=rn(t,"x","tanh");return kt.runKernel(function(t,n){var r=t.tanh(e);return n([r]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return Cn(1).sub(n.square()).mulStrict(t)}}})}});function hu(t,e,n,r,o,a){var i,s,u=rn(t,"x","batchNorm"),l=rn(e,"mean","batchNorm"),c=rn(n,"variance","batchNorm");return null!=o&&(i=rn(o,"scale","batchNorm")),null!=r&&(s=rn(r,"offset","batchNorm")),h(2===u.rank,function(){return"Error in batchNorm3D: x must be rank 3 but got rank "+u.rank+"."}),h(2===l.rank||1===l.rank,function(){return"Error in batchNorm2D: mean must be rank 2 or rank 1 but got rank "+l.rank+"."}),h(2===c.rank||1===c.rank,function(){return"Error in batchNorm2D: variance must be rank 2 or rank 1 but got rank "+c.rank+"."}),null!=i&&h(2===i.rank||1===i.rank,function(){return"Error in batchNorm2D: scale must be rank 2 or rank 1 but got rank "+i.rank+"."}),null!=s&&h(2===s.rank||1===s.rank,function(){return"Error in batchNorm2D: offset must be rank 2 or rank 1 but got rank "+s.rank+"."}),du(u,l,c,s,i,a)}function pu(t,e,n,r,o,a){var i,s,u=rn(t,"x","batchNorm"),l=rn(e,"mean","batchNorm"),c=rn(n,"variance","batchNorm");return null!=o&&(i=rn(o,"scale","batchNorm")),null!=r&&(s=rn(r,"offset","batchNorm")),h(3===u.rank,function(){return"Error in batchNorm3D: x must be rank 3 but got rank "+u.rank+"."}),h(3===l.rank||1===l.rank,function(){return"Error in batchNorm3D: mean must be rank 3 or rank 1 but got rank "+l.rank+"."}),h(3===c.rank||1===c.rank,function(){return"Error in batchNorm3D: variance must be rank 3 or rank 1 but got rank "+c.rank+"."}),null!=i&&h(3===i.rank||1===i.rank,function(){return"Error in batchNorm3D: scale must be rank 3 or rank 1 but got rank "+i.rank+"."}),null!=s&&h(3===s.rank||1===s.rank,function(){return"Error in batchNorm3D: offset must be rank 3 or rank 1 but got rank "+s.rank+"."}),du(u,l,c,s,i,a)}function fu(t,e,n,r,o,a){var i,s,u=rn(t,"x","batchNorm"),l=rn(e,"mean","batchNorm"),c=rn(n,"variance","batchNorm");return null!=o&&(i=rn(o,"scale","batchNorm")),null!=r&&(s=rn(r,"offset","batchNorm")),h(4===u.rank,function(){return"Error in batchNorm4D: x must be rank 4 but got rank "+u.rank+"."}),h(4===l.rank||1===l.rank,function(){return"Error in batchNorm4D: mean must be rank 4 or rank 1 but got rank "+l.rank+"."}),h(4===c.rank||1===c.rank,function(){return"Error in batchNorm4D: variance must be rank 4 or rank 1 but got rank "+c.rank+"."}),null!=i&&h(4===i.rank||1===i.rank,function(){return"Error in batchNorm4D: scale must be rank 4 or rank 1 but got rank "+i.rank+"."}),null!=s&&h(4===s.rank||1===s.rank,function(){return"Error in batchNorm4D: offset must be rank 4 or rank 1 but got rank "+s.rank+"."}),du(u,l,c,s,i,a)}function du(t,e,n,r,o,a){null==a&&(a=.001);var i,s,u,l=rn(t,"x","batchNorm"),c=rn(e,"mean","batchNorm"),p=rn(n,"variance","batchNorm");null!=o&&(i=rn(o,"scale","batchNorm")),null!=r&&(s=rn(r,"offset","batchNorm")),h(c.rank===p.rank,function(){return"Batch normalization gradient requires mean and variance to have equal ranks."}),h(null==s||c.rank===s.rank,function(){return"Batch normalization gradient requires mean and offset to have equal ranks."}),h(null==i||c.rank===i.rank,function(){return"Batch normalization gradient requires mean and scale to have equal ranks."}),u=0===l.rank||1===l.rank?l.as4D(1,1,1,l.size):2===l.rank?l.as4D(1,1,l.shape[0],l.shape[1]):3===l.rank?l.as4D(1,l.shape[0],l.shape[1],l.shape[2]):l;return kt.runKernel(function(t,e){var n=t.batchNormalization(u,vu(c),vu(p),a,vu(i),vu(s));return e([l,c,p,i]),n},{$x:l,$mean:c,$variance:p,$scale:i,$offset:s},function(t,e){var n=e,r=n[0],o=n[1],i=n[2],s=n[3],l=null==s?Cn(1):s,c=no(o.shape,u.shape),h=[];if(1===o.rank){for(var p=0;p0&&(e=e.sum(n)),e.reshape(r.shape)},$b:function(){var e=t,n=no(o.shape,a);return n.length>0&&(e=e.sum(n)),e.reshape(o.shape)}}})}}),_u=mn({addN_:function(t){h(Array.isArray(t),function(){return"The argument passed to tf.addN() must be a list of tensors"}),h(t.length>=1,function(){return"Must pass at least one tensor to tf.addN(), but got "+t.length});var e=t.map(function(t,e){return rn(t,"tensors"+e,"addN")}),n=e[0];e.forEach(function(t){if(t.dtype!==n.dtype)throw new Error("All tensors passed to tf.addN() must have the same dtype")}),e.forEach(function(t){if(!m(t.shape,n.shape))throw new Error("All tensors passed to tf.addN() must have the same shape")});var r=e;return kt.runKernel(function(t){return t.addN(e)},r,function(t){var n={};return e.forEach(function(e,r){n[r]=function(){return t.clone()}}),n})}}),Ou=mn({addStrict_:function(t,e){var n=rn(t,"a","addStrict"),r=rn(e,"b","addStrict");return p(n.shape,r.shape,"Error in addStrict: "),n.add(r)}}),Fu=mn({atan2_:function(t,e){var n,r=rn(t,"a","atan2"),o=rn(e,"b","atan2");n=xt(r,o),r=n[0],o=n[1];var a=ro(r.shape,o.shape);return kt.runKernel(function(t,e){var n=t.atan2(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){var e=Du(n.square(),r.square()),o=t.mul(r.div(e)),i=no(n.shape,a);return i.length>0&&(o=o.sum(i)),o.reshape(n.shape)},$b:function(){var e=Du(n.square(),r.square()),o=js(t.mul(n.div(e))),i=no(r.shape,a);return i.length>0&&(o=o.sum(i)),o.reshape(r.shape)}}})}}),Mu=mn({div_:function(t,e){var n,r=rn(t,"a","div"),o=rn(e,"b","div");if(n=xt(r,o),r=n[0],o=n[1],"int32"===r.dtype&&"int32"===o.dtype)return Pu(r,o);var a=ro(r.shape,o.shape);return kt.runKernel(function(t,e){var n=t.realDivide(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){var e=t.div(r.toFloat()),o=no(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=no(r.shape,a);o.length>0&&(e=e.sum(o).reshape(r.shape));var i=r.square();return e.div(i.toFloat()).neg()}}})}}),Bu=mn({divStrict_:function(t,e){var n=rn(t,"a","div"),r=rn(e,"b","div");return p(n.shape,r.shape,"Error in divideStrict: "),n.div(r)}}),Pu=mn({floorDiv_:function(t,e){var n,r=rn(t,"a","floorDiv"),o=rn(e,"b","floorDiv");n=xt(r,o),r=n[0],o=n[1];var a=ro(r.shape,o.shape);return kt.runKernel(function(t,e){var n=t.floorDiv(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){var e=t.div(r.toFloat()),o=no(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=no(r.shape,a);o.length>0&&(e=e.sum(o).reshape(r.shape));var i=r.square();return e.div(i.toFloat()).neg()}}})}}),Lu=mn({maximum_:function(t,e){var n,r=rn(t,"a","maximum"),o=rn(e,"b","maximum");return n=xt(r,o),r=n[0],o=n[1],"bool"===r.dtype&&(r=r.toInt(),o=o.toInt()),ro(r.shape,o.shape),kt.runKernel(function(t,e){var n=t.maximum(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){return t.mul(n.greaterEqual(r).toFloat())},$b:function(){return t.mul(n.less(r).toFloat())}}})}}),Wu=mn({maximumStrict_:function(t,e){var n=rn(t,"a","maximumStrict"),r=rn(e,"b","maximumStrict");return p(n.shape,r.shape,"Error in maximumStrict: "),n.maximum(r)}}),Uu=mn({minimum_:function(t,e){var n,r=rn(t,"a","minimum"),o=rn(e,"b","minimum");return n=xt(r,o),r=n[0],o=n[1],"bool"===r.dtype&&(r=r.toInt(),o=o.toInt()),ro(r.shape,o.shape),kt.runKernel(function(t,e){var n=t.minimum(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){return t.mul(n.lessEqual(r).toFloat())},$b:function(){return t.mul(n.greater(r).toFloat())}}})}}),Vu=mn({minimumStrict_:function(t,e){var n=rn(t,"a","minimumStrict"),r=rn(e,"b","minimumStrict");return p(n.shape,r.shape,"Error in minimumStrict: "),n.minimum(r)}}),zu=mn({mod_:function(t,e){var n,r=rn(t,"a","mod"),o=rn(e,"b","mod");n=xt(r,o),r=n[0],o=n[1];var a=ro(r.shape,o.shape);return kt.runKernel(function(t,e){var n=t.mod(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){var e=no(n.shape,a);return e.length>0?t.sum(e).reshape(n.shape):t},$b:function(){var e=t.mul(n.div(r).floor().neg()),o=no(r.shape,a);return o.length>0?e.sum(o).reshape(r.shape):e}}})}}),Gu=mn({modStrict_:function(t,e){var n=rn(t,"a","modStrict"),r=rn(e,"b","modStrict");return p(n.shape,r.shape,"Error in modStrict: "),n.mod(r)}}),Hu=mn({mul_:function(t,e){var n,r=rn(t,"a","mul"),o=rn(e,"b","mul");n=xt(r,o),r=n[0],o=n[1];var a=ro(r.shape,o.shape);return kt.runKernel(function(t,e){var n=t.multiply(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){var e=t.mul(r.toFloat()),o=no(n.shape,a);return o.length>0?e.sum(o).reshape(n.shape):e},$b:function(){var e=t.mul(n.toFloat()),o=no(r.shape,a);return o.length>0?e.sum(o).reshape(r.shape):e}}})}}),qu=mn({mulStrict_:function(t,e){var n=rn(t,"a","mul"),r=rn(e,"b","mul");return p(n.shape,r.shape,"Error in multiplyStrict: "),n.mul(r)}}),$u=mn({pow_:function(t,e){var n=rn(t,"base","pow"),r=rn(e,"exp","pow"),o=ro(n.shape,r.shape);return t=n.cast(gt(n.dtype,r.dtype)),e=r.cast(gt(n.dtype,r.dtype)),kt.runKernel(function(t,e){var o=t.pow(n,r);return e([n,r,o]),o},{$base:n,$exp:r},function(t,e){var n=e[0],r=e[1],a=e[2];return{$base:function(){var e=r.toFloat(),a=t.mul(e.mul(n.pow(e.sub(Cn(1))))),i=no(n.shape,o);return i.length>0&&(a=a.sum(i)),a.reshape(n.shape)},$exp:function(){var e=n.greater(0),i=n.log().where(e,Mn(n)),s=t.mul(a.mul(i)),u=no(r.shape,o);return u.length>0&&(s=s.sum(u)),s.reshape(r.shape)}}})}}),Ku=mn({powStrict_:function(t,e){return p(t.shape,e.shape,"Error in powStrict: "),t.pow(e)}}),ju=mn({squaredDifference_:function(t,e){var n,r=rn(t,"a","squaredDifference"),o=rn(e,"b","squaredDifference");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t,e){var n=t.squaredDifference(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1],o=Cn(2);return{$a:function(){return t.mul(n.sub(r).mul(o))},$b:function(){return t.mul(r.sub(n).mul(o))}}})}}),Xu=mn({squaredDifferenceStrict_:function(t,e){var n=rn(t,"a","squaredDifferenceStrict"),r=rn(e,"b","squaredDifferenceStrict");return p(n.shape,r.shape,"Error in squaredDifferenceStrict: "),n.squaredDifference(r)}}),Yu=mn({sub_:function(t,e){var n,r=rn(t,"a","sub"),o=rn(e,"b","sub");n=xt(r,o),r=n[0],o=n[1];var a=ro(r.shape,o.shape);return kt.runKernel(function(t){return t.subtract(r,o)},{$a:r,$b:o},function(t){return{$a:function(){var e=t,n=no(r.shape,a);return n.length>0&&(e=e.sum(n)),e.reshape(r.shape)},$b:function(){var e=t,n=no(o.shape,a);return n.length>0&&(e=e.sum(n)),e.neg().reshape(o.shape)}}})}}),Qu=mn({subStrict_:function(t,e){var n=rn(t,"a","subStrict"),r=rn(e,"b","subStrict");return p(n.shape,r.shape,"Error in subStrict: "),n.sub(r)}});var Ju=mn({equal_:function(t,e){var n,r=rn(t,"a","equal"),o=rn(e,"b","equal");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t){return t.equal(r,o)},{$a:r,$b:o})}}),Zu=mn({equalStrict_:function(t,e){var n=rn(t,"a","equalStrict"),r=rn(e,"b","equalStrict");return p(n.shape,r.shape,"Error in equalStrict: "),n.equal(r)}}),tl=mn({greater_:function(t,e){var n,r=rn(t,"a","greater"),o=rn(e,"b","greater");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t){return t.greater(r,o)},{$a:r,$b:o})}}),el=mn({greaterEqual_:function(t,e){var n,r=rn(t,"a","greaterEqual"),o=rn(e,"b","greaterEqual");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t,e){var n=t.greaterEqual(r,o);return e([r,o]),n},{$a:r,$b:o},function(t,e){var n=e[0],r=e[1];return{$a:function(){return Mn(n)},$b:function(){return Mn(r)}}})}}),nl=mn({greaterEqualStrict_:function(t,e){var n=rn(t,"a","greaterEqualStrict"),r=rn(e,"b","greaterEqualStrict");return p(n.shape,r.shape,"Error in greaterEqualStrict: "),n.greaterEqual(r)}}),rl=mn({greaterStrict_:function(t,e){var n=rn(t,"a","greaterStrict"),r=rn(e,"b","greaterStrict");return p(n.shape,r.shape,"Error in greaterStrict: "),n.greater(r)}}),ol=mn({less_:function(t,e){var n,r=rn(t,"a","less"),o=rn(e,"b","less");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t){return t.less(r,o)},{$a:r,$b:o})}}),al=mn({lessEqual_:function(t,e){var n,r=rn(t,"a","lessEqual"),o=rn(e,"b","lessEqual");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t){return t.lessEqual(r,o)},{$a:r,$b:o})}}),il=mn({lessEqualStrict_:function(t,e){var n=rn(t,"a","lessEqualStrict"),r=rn(e,"b","lessEqualStrict");return p(n.shape,r.shape,"Error in lessEqualStrict: "),n.lessEqual(r)}}),sl=mn({lessStrict_:function(t,e){var n=rn(t,"a","lessStrict"),r=rn(e,"b","lessStrict");return p(n.shape,r.shape,"Error in lessStrict: "),n.less(r)}}),ul=mn({notEqual_:function(t,e){var n,r=rn(t,"a","notEqual"),o=rn(e,"b","notEqual");return n=xt(r,o),r=n[0],o=n[1],ro(r.shape,o.shape),kt.runKernel(function(t){return t.notEqual(r,o)},{$a:r,$b:o})}}),ll=mn({notEqualStrict_:function(t,e){var n=rn(t,"a","notEqualStrict"),r=rn(e,"b","notEqualStrict");return p(n.shape,r.shape,"Error in notEqualStrict: "),n.notEqual(r)}});function cl(t,e){for(var n=[],r=t;r0,function(){return"mask cannot be scalar"}),p(u.slice(i,i+s),a.shape,"mask's shape must match the first K dimensions of tensor's shape,"),l=1,c=i;c=2&&i.rank>=2&&a.rank===i.rank,function(){return"Error in matMul: inputs must have the same rank of at least 2, got ranks "+a.rank+" and "+i.rank+"."}),h(m(p,f),function(){return"Error in matMul: outer dimensions ("+p+") and ("+f+") of Tensors with shapes "+a.shape+" and "+i.shape+" must match."}),h(s===u,function(){return"Error in matMul: inner shapes ("+s+") and ("+u+") of Tensors with shapes "+a.shape+" and "+i.shape+" and transposeA="+n+" and transposeB="+r+" must match."});var y=a.shape.slice(0,-2).concat([l,c]),x=n?a.as3D(d,s,l):a.as3D(d,l,s),b=r?i.as3D(g,c,u):i.as3D(g,u,c);return kt.runKernel(function(t,e){var o=t.batchMatMul(x,b,n,r);return e([x,b]),o},{$a:x,$b:b},function(t,e){var o=e,a=o[0],i=o[1];return n||r?!n&&r?{$a:function(){return t.matMul(i,!1,!1)},$b:function(){return t.matMul(a,!0,!1)}}:n&&!r?{$a:function(){return i.matMul(t,!1,!0)},$b:function(){return a.matMul(t,!1,!1)}}:{$a:function(){return i.matMul(t,!0,!0)},$b:function(){return t.matMul(a,!0,!0)}}:{$a:function(){return t.matMul(i,!1,!0)},$b:function(){return a.matMul(t,!0,!1)}}}).reshape(y)}}),Tl=mn({dot_:function(t,e){var n=rn(t,"t1","dot"),r=rn(e,"t2","dot");h(!(1!==n.rank&&2!==n.rank||1!==r.rank&&2!==r.rank),function(){return"Error in dot: inputs must all be rank 1 or 2, but got ranks "+n.rank+" and "+r.rank+"."});var o=1===n.rank?n.size:n.shape[1],a=1===r.rank?r.size:r.shape[0];return h(o===a,function(){return"Error in dot: inner dimensions of inputs must match, but got "+o+" and "+a+"."}),1===n.rank&&1===r.rank?n.as2D(1,-1).matMul(r.as2D(-1,1)).asScalar():1===n.rank&&2===r.rank?n.as2D(1,-1).matMul(r.as2D(r.shape[0],r.shape[1])).as1D():2===n.rank&&1===r.rank?n.matMul(r.as2D(-1,1)).as1D():n.matMul(r.as2D(r.shape[0],r.shape[1]))}}),Dl=mn({outerProduct_:function(t,e){var n=rn(t,"v1","outerProduct"),r=rn(e,"v2","outerProduct");return h(1===n.rank&&1===r.rank,function(){return"Error in outerProduct: inputs must be rank 1, but got ranks "+n.rank+" and "+r.rank+"."}),n.as2D(-1,1).matMul(r.as2D(1,-1))}});var _l=mn({reverse_:function(t,e){var n=rn(t,"x","reverse");if(0===n.rank)return n.clone();var r=E(e,n.shape);return kt.runKernel(function(t){return t.reverse(n,r)},{$x:n},function(t){return{$x:function(){return t.reverse(r)}}}).reshapeAs(n)}}),Ol=mn({reverse1d_:function(t){var e=rn(t,"x","reverse");return h(1===e.rank,function(){return"Error in reverse1D: x must be rank 1 but got rank "+e.rank+"."}),_l(e,0)}}),Fl=mn({reverse2d_:function(t,e){var n=rn(t,"x","reverse");return h(2===n.rank,function(){return"Error in reverse2D: x must be rank 2 but got rank "+n.rank+"."}),_l(n,e)}}),Ml=mn({reverse3d_:function(t,e){var n=rn(t,"x","reverse");return h(3===n.rank,function(){return"Error in reverse3D: x must be rank 3 but got rank "+n.rank+"."}),_l(n,e)}}),Bl=mn({reverse4d_:function(t,e){var n=rn(t,"x","reverse");return h(4===n.rank,function(){return"Error in reverse4D: x must be rank 4 but got rank "+n.rank+"."}),_l(n,e)}});function Pl(t,e,n,r,o,a){var i=rn(t,"x","maxPool"),s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),null==r&&(r=[1,1]),h(4===s.rank,function(){return"Error in maxPool: input must be rank 4 but got rank "+s.rank+"."}),h(vo(n,r),function(){return"Error in maxPool: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+r+"'"}),null!=a&&h(g(o),function(){return"Error in maxPool: pad must be an integer when using, dimRoundingMode "+a+" but got pad "+o+"."});var l=oo(s.shape,e,n,r,o,a),c=kt.runKernel(function(t,e){var n=t.maxPool(s,l);return e([s,n]),n},{x:s},function(t,a){var i=a[0],s=a[1];return{x:function(){return function(t,e,n,r,o,a,i,s){var u=rn(t,"dy","maxPoolBackprop"),l=rn(e,"input","maxPoolBackprop"),c=rn(n,"output","maxPoolBackprop");h(l.rank===u.rank,function(){return"Rank of input ("+l.rank+") does not match rank of dy ("+u.rank+")"}),null==a&&(a=[1,1]),h(vo(o,a),function(){return"Error in maxPoolBackProp: Either strides or dilations must be 1. Got strides "+o+" and dilations '"+a+"'"}),h(4===u.rank,function(){return"Error in maxPoolBackprop: dy must be rank 4 but got rank "+u.rank+"."}),h(4===l.rank,function(){return"Error in maxPoolBackprop: input must be rank 4 but got rank "+l.rank+"."}),null!=s&&h(g(i),function(){return"Error in maxPoolBackprop: pad must be an integer when using, dimRoundingMode "+s+" but got pad "+i+"."});var p=oo(l.shape,r,o,a,i,s);return kt.runKernel(function(t){return t.maxPoolBackprop(u,l,c,p)},{$dy:u,$input:l})}(t,i,s,e,n,r,o)}}});return u?c.as3D(c.shape[1],c.shape[2],c.shape[3]):c}function Ll(t,e,n,r,o,a){var i=rn(t,"x","avgPool","float32");null==r&&(r=[1,1]),h(vo(n,r),function(){return"Error in avgPool: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+r+"'"});var s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),h(4===s.rank,function(){return"Error in avgPool: x must be rank 4 but got rank "+s.rank+"."}),null!=a&&h(g(o),function(){return"Error in avgPool: pad must be an integer when using, dimRoundingMode "+a+" but got pad "+o+"."});var l=oo(s.shape,e,n,r,o,a),c=kt.runKernel(function(t){return t.avgPool(s,l)},{x:s},function(t){return{x:function(){return function(t,e,n,r,o,a){var i=rn(t,"dy","avgPoolBackprop"),s=rn(e,"input","avgPoolBackprop");h(s.rank===i.rank,function(){return"Rank of input ("+s.rank+") does not match rank of dy ("+i.rank+")"}),null==o&&(o=[1,1]),h(vo(r,o),function(){return"Error in avgPoolBackprop: Either strides or dilations must be 1. Got strides "+r+" and dilations '"+o+"'"});var u=s,l=i,c=!1;3===s.rank&&(c=!0,u=s.as4D(1,s.shape[0],s.shape[1],s.shape[2]),l=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),h(4===l.rank,function(){return"Error in avgPoolBackprop: dy must be rank 4 but got rank "+l.rank+"."}),h(4===u.rank,function(){return"Error in avgPoolBackprop: input must be rank 4 but got rank "+u.rank+"."});var p=oo(u.shape,n,r,o,a),f=kt.runKernel(function(t){return t.avgPoolBackprop(l,u,p)},{dy4D:l,input4D:u});return c?f.as3D(f.shape[1],f.shape[2],f.shape[3]):f}(t,s,e,n,r,o)}}});return c=c.cast(i.dtype),u?c.as3D(c.shape[1],c.shape[2],c.shape[3]):c}var Wl=mn({maxPool_:function(t,e,n,r,o){return Pl(t,e,n,1,r,o)}}),Ul=mn({avgPool_:function(t,e,n,r,o){return Ll(t,e,n,1,r,o)}}),Vl=mn({pool_:function(t,e,n,r,o,a){null==o&&(o=[1,1]),null==a&&(a=1),0===r&&(r="valid");var i=rn(t,"x","maxPool"),s=i,u=!1;3===i.rank&&(u=!0,s=i.as4D(1,i.shape[0],i.shape[1],i.shape[2])),h(vo(a,o),function(){return"Error in pool: Either strides or dilations must be 1. Got strides "+a+" and dilations '"+o+"'"});var l,c=oo(s.shape,e,a,o,r),p=[c.dilationHeight,c.dilationWidth];l="same"===r?function(t,e){var n=t.map(function(t,n){return t+(t-1)*(e[n]-1)}).map(function(t){return t-1}),r=n.map(function(t){return Math.floor(t/2)}),o=n.map(function(t,e){return t-r[e]});return n.map(function(t,e){return[r[e],o[e]]})}([c.filterHeight,c.filterWidth],p):[[0,0],[0,0]];var f=1===p[0]&&1===p[1],d=function(t,e,n){var r=n.map(function(t){return t[0]}),o=n.map(function(t){return t[1]}),a=t.concat(r,o),i=e.map(function(t,e){return(t-a[e]%t)%t}),s=o.map(function(t,e){return t+i[e]}),u=e.map(function(t,e){return[r[e],s[e]]}),l=e.map(function(t,e){return[0,i[e]]});return[u,l]}([c.inHeight,c.inWidth],p,l),v=d[0],m=d[1],g=f?r:"valid",y=f?s:wr(s,p,v),x=("avg"===n?function(){return Ll(y,e,a,1,g)}:function(){return Pl(y,e,a,1,g)})(),b=f?x:nr(x,p,m);return u?b.as3D(b.shape[1],b.shape[2],b.shape[3]):b}}),zl=mn({maxPool3d_:function(t,e,n,r,o,a,i){void 0===a&&(a="NDHWC");var s=rn(t,"x","maxPool3d"),u=s,l=!1;4===s.rank&&(l=!0,u=s.as5D(1,s.shape[0],s.shape[1],s.shape[2],s.shape[3])),null==i&&(i=[1,1,1]),h(5===u.rank,function(){return"Error in maxPool3d: x must be rank 5 but got rank "+u.rank+"."}),h("NDHWC"===a,function(){return"Error in maxPool3d: Only NDHWC is currently supported, but got dataFormat of "+a}),h(vo(n,i),function(){return"Error in maxPool3d: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+i+"'"}),null!=o&&h(g(r),function(){return"Error in maxPool3d: pad must be an integer when using, dimRoundingMode "+o+" but got pad "+r+"."});var c=ao(u.shape,e,n,i,r,o,a),p=kt.runKernel(function(t,e){var n=t.maxPool3d(u,c);return e([u,n]),n},{x:u},function(t,a){var s=a[0],u=a[1];return{x:function(){return function(t,e,n,r,o,a,i,s){var u=rn(t,"dy","maxPool3dBackprop"),l=rn(e,"input","maxPool3dBackprop"),c=rn(n,"output","maxPool3dBackprop"),p=u,f=l,d=c,v=!1;4===l.rank&&(v=!0,p=u.as5D(1,u.shape[0],u.shape[1],u.shape[2],u.shape[3]),f=l.as5D(1,l.shape[0],l.shape[1],l.shape[2],l.shape[3]),d=c.as5D(1,c.shape[0],c.shape[1],c.shape[2],c.shape[3])),h(5===p.rank,function(){return"Error in maxPool3dBackprop: dy must be rank 5 but got rank "+p.rank+"."}),h(5===f.rank,function(){return"Error in maxPool3dBackprop: input must be rank 5 but got rank "+f.rank+"."}),h(5===d.rank,function(){return"Error in maxPool3dBackprop: output must be rank 5 but got rank "+d.rank+"."}),null==a&&(a=[1,1,1]),h(vo(o,a),function(){return"Error in maxPool3dBackprop: Either strides or dilations must be 1. Got strides "+o+" and dilations '"+a+"'"}),null!=s&&h(g(i),function(){return"Error in maxPool3dBackprop: pad must be an integer when using, dimRoundingMode "+s+" but got pad "+i+"."});var m=ao(f.shape,r,o,a,i,s),y=kt.runKernel(function(t){return t.maxPool3dBackprop(p,f,d,m)},{dy5D:p,input5D:f});return v?y.as4D(y.shape[1],y.shape[2],y.shape[3],y.shape[4]):y}(t,s,u,e,n,i,r,o)}}});return l?p.as4D(p.shape[1],p.shape[2],p.shape[3],p.shape[4]):p}}),Gl=mn({avgPool3d_:function(t,e,n,r,o,a,i){void 0===a&&(a="NDHWC");var s=rn(t,"x","avgPool3d","float32"),u=s,l=!1;4===s.rank&&(l=!0,u=s.as5D(1,s.shape[0],s.shape[1],s.shape[2],s.shape[3])),null==i&&(i=[1,1,1]),h(5===u.rank,function(){return"Error in avgPool3d: x must be rank 5 but got rank "+u.rank+"."}),h("NDHWC"===a,function(){return"Error in avgPool3d: Only NDHWC is currently supported, but got dataFormat of "+a}),h(vo(n,i),function(){return"Error in avgPool3d: Either strides or dilations must be 1. Got strides "+n+" and dilations '"+i+"'"}),null!=o&&h(g(r),function(){return"Error in avgPool3d: pad must be an integer when using, dimRoundingMode "+o+" but got pad "+r+"."});var c=ao(u.shape,e,n,i,r,o,a),p=kt.runKernel(function(t){return t.avgPool3d(u,c)},{x:u},function(t){return{x:function(){return function(t,e,n,r,o,a,i){var s=rn(t,"dy","avgPool3dBackprop"),u=rn(e,"input","avgPool3dBackprop"),l=s,c=u,p=!1;4===u.rank&&(p=!0,l=s.as5D(1,s.shape[0],s.shape[1],s.shape[2],s.shape[3]),c=u.as5D(1,u.shape[0],u.shape[1],u.shape[2],u.shape[3])),h(5===l.rank,function(){return"Error in avgPool3dBackprop: dy must be rank 5 but got rank "+l.rank+"."}),h(5===c.rank,function(){return"Error in avgPool3dBackprop: input must be rank 5 but got rank "+c.rank+"."}),null==o&&(o=[1,1,1]),h(vo(r,o),function(){return"Error in avgPool3dBackprop: Either strides or dilations must be 1. Got strides "+r+" and dilations '"+o+"'"}),null!=i&&h(g(a),function(){return"Error in maxPool3dBackprop: pad must be an integer when using, dimRoundingMode "+i+" but got pad "+a+"."});var f=ao(c.shape,n,r,o,a,i),d=kt.runKernel(function(t){return t.avgPool3dBackprop(l,c,f)},{dy5D:l,input5D:c});return p?d.as4D(d.shape[1],d.shape[2],d.shape[3],d.shape[4]):d}(t,u,e,n,i,r,o)}}});return p=p.cast(u.dtype),l?p.as4D(p.shape[1],p.shape[2],p.shape[3],p.shape[4]):p}});var Hl=mn({slice_:function(t,e,n){var r,o,a=rn(t,"x","slice");if(0===a.rank)throw new Error("Slicing scalar is not possible");(r="number"==typeof e?[e].concat(new Array(a.rank-1).fill(0)):e.length=0?t:(h(-1===t,function(){return"Negative size values should be exactly -1 but got "+t+" for the slice() size at index "+e+"."}),a.shape[e]-r[e])}),function(t,e,n){h(t.rank===e.length,function(){return"Error in slice"+t.rank+"D: Length of begin "+e+" must match the rank of the array ("+t.rank+")."}),h(t.rank===n.length,function(){return"Error in slice"+t.rank+"D: Length of size "+n+" must match the rank of the array ("+t.rank+")."});for(var r=function(r){h(e[r]+n[r]<=t.shape[r],function(){return"Error in slice"+t.rank+"D: begin["+r+"] + size["+r+"] ("+(e[r]+n[r])+") would overflow input.shape["+r+"] ("+t.shape[r]+")"})},o=0;o0&&(e=e.sum(a)),e.reshape(r.shape)}}})}}),cc=mn({relu_:function(t){var e=rn(t,"x","relu");return"bool"===e.dtype?e.toInt():kt.runKernel(function(t,n){var r=t.relu(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){return t.mulStrict(n.step().toFloat())}}})}}),hc=mn({relu6_:function(t){var e=rn(t,"x","relu6");return"bool"===e.dtype?e.toInt():kt.runKernel(function(t,n){var r=t.relu6(e);return n([e]),r},{$x:e},function(t,e){var n=e[0],r=n.lessEqual(6).mul(n.step());return{$x:function(){return t.mulStrict(r.toFloat())}}})}}),pc=mn({selu_:function(t){var e=rn(t,"x","selu");return kt.runKernel(function(t,n){var r=t.selu(e);return n([e]),r},{$x:e},function(t,e){var n=e[0];return{$x:function(){var e=n.greater(Cn(0)),r=Cn(Yi),o=Cn(Qi),a=t.mul(o),i=t.mul(r).mul(n.toFloat().exp());return Au(e,a,i)}}})}});var fc=mn({transpose_:function(t,e){var n=rn(t,"x","transpose");return null==e&&(e=n.shape.map(function(t,e){return e}).reverse()),h(n.rank===e.length,function(){return"Error in transpose: rank of input "+n.rank+" must match length of perm "+e+"."}),e.forEach(function(t){h(t>=0&&to)throw new Error("'k' passed to topk() must be <= the last dimension ("+o+") but got "+e);var a=kt.runKernel(function(t){return t.topk(r,e,n)},{$x:r});return{values:a[0],indices:a[1]}}});var wc=mn({scatterND_:function(t,e,n){var r=rn(t,"indices","scatterND","int32"),o=rn(e,"updates","scatterND");return Br(o,r,n),kt.runKernel(function(t){return t.scatterND(r,o,n)},{$indices:r,$updates:o})}});var Cc=mn({fft_:function(t){h("complex64"===t.dtype,function(){return"The dtype for tf.spectral.fft() must be complex64 but got "+t.dtype+"."});var e=t.shape[t.shape.length-1],n=t.size/e,r=t.as2D(n,e);return kt.runKernel(function(t){return t.fft(r)},{input:t}).reshape(t.shape)}}),Ec=mn({ifft_:function(t){h("complex64"===t.dtype,function(){return"The dtype for tf.spectral.ifft() must be complex64 but got "+t.dtype+"."});var e=t.shape[t.shape.length-1],n=t.size/e,r=t.as2D(n,e);return kt.runKernel(function(t){return t.ifft(r)},{input:t}).reshape(t.shape)}}),Rc=mn({rfft_:function(t,e){h("float32"===t.dtype,function(){return"The dtype for rfft() must be real value but got "+t.dtype});var n,r=t.shape[t.shape.length-1],o=t.size/r;if(null!=e&&er){var s=t.shape.map(function(t){return t});s[t.shape.length-1]=e-r,n=t.concat(Tn(s),t.shape.length-1),r=e}else n=t;var u=n.zerosLike(),l=gn(n,u).as2D(o,r),c=Cc(l),p=Math.floor(r/2)+1,f=yn(c),d=xn(c),v=f.split([p,r-p],f.shape.length-1),m=d.split([p,r-p],d.shape.length-1),g=n.shape.slice();return g[n.shape.length-1]=p,gn(v[0],m[0]).reshape(g)}}),Ic=mn({irfft_:function(t){var e=t.shape[t.shape.length-1],n=t.size/e;if(e<=2){var r=t.as2D(n,e),o=Ec(r);return yn(o)}var a=[n,2*(e-1)],i=yn(t).as2D(n,e),s=xn(t).as2D(n,e),u=i.slice([0,1],[n,e-2]).reverse(1),l=s.slice([0,1],[n,e-2]).reverse(1).mul(Cn(-1)),c=i.concat(u,1),h=s.concat(l,1);return r=gn(c,h).as2D(a[0],a[1]),o=Ec(r),yn(o)}}),kc=Object.freeze({fft:Cc,ifft:Ec,rfft:Rc,irfft:Ic});var Nc=mn({sparseToDense_:function(t,e,n,r){void 0===r&&(r=0);var o=rn(t,"sparseIndices","sparseToDense","int32"),a=rn(e,"sparseValues","sparseToDense"),i=rn(r,"defaultValue","sparseToDense",a.dtype);return function(t,e,n,r){if("int32"!==t.dtype)throw new Error("tf.sparseToDense() expects the indices to be int32 type, but the dtype was "+t.dtype+".");if(t.rank>2)throw new Error("sparseIndices should be a scalar, vector, or matrix, but got shape "+t.shape+".");var o=t.rank>0?t.shape[0]:1,a=t.rank>1?t.shape[1]:1;if(n.length!==a)throw new Error("outputShape has incorrect number of elements:, "+n.length+", should be: "+a+".");var i=e.size;if(0!==e.rank&&(1!==e.rank||i!==o))throw new Error("sparseValues has incorrect shape "+e.shape+", should be [] or ["+o+"]");if(e.dtype!==r.dtype)throw new Error("sparseValues.dtype must match defaultValues.dtype")}(o,a,n,i),kt.runKernel(function(t){return t.sparseToDense(o,a,n,i)},{$sparseIndices:o,$sparseValues:a,$defaultValue:i})}});var Sc=mn({gatherND_:function(t,e){var n=rn(e,"indices","gatherND","int32"),r=rn(t,"x","gatherND");return kt.runKernel(function(t){return t.gatherND(r,n)},{$x:r,$indices:n})}});var Ac=mn({diag_:function(t){var e=rn(t,"x","diag").flatten(),n=t.shape.concat(t.shape);return kt.runKernel(function(t){return t.diag(e)},{$x:e}).reshape(n)}});var Tc=mn({dropout_:function(t,e,n,r){var o=rn(t,"x","dropout");if(h("float32"===o.dtype,function(){return"x has to be a floating point tensor since it's going to be scaled, but got a "+o.dtype+" tensor instead."}),h(e>=0&&e<1,function(){return"rate must be a float in the range [0, 1), but got "+e+"."}),0===e)return t instanceof ut?o.clone():o;var a=function(t,e){if(null==e)return t.shape.slice();if(m(t.shape,e))return e;if(t.shape.length===e.length){for(var n=[],r=0;r1,function(){return"inTopK() expects the predictions to be of rank 2 or higher, but got "+n.rank}),h(n.rank-1===a.rank,function(){return"predictions rank should be 1 larger than targets rank, but got predictions rank "+n.rank+" and targets rank "+a.rank}),p(n.shape.slice(0,n.shape.length-1),a.shape,"predictions's shape should be align with the targets' shape, except the last dimension."),i=n.shape[n.shape.length-1],h(o>0&&o<=i,function(){return"'k' passed to inTopK() must be > 0 && <= the predictions last dimension ("+i+"), but got "+o}),[4,n.data()];case 1:return s=r.sent(),[4,a.data()];case 2:for(u=r.sent(),l=[s.length/i,i],f=l[1],d=I("bool",c=l[0]),v=0;v1?s.div(Cn(i)):s}if(n===Pc.SUM_BY_NONZERO_WEIGHTS){if(null==o)return a.sum().div(Cn(r.size));var u=o.mul(An(r.shape)).notEqual(Cn(0)).sum().toFloat();return a.sum().div(u)}throw Error("Unknown reduction: "+n)}}),Vc=mn({cosineDistance_:function(t,e,n,r,o){void 0===o&&(o=Pc.SUM_BY_NONZERO_WEIGHTS);var a=rn(t,"labels","cosineDistance"),i=rn(e,"predictions","cosineDistance"),s=null;null!=r&&(s=rn(r,"weights","cosineDistance")),p(a.shape,i.shape,"Error in cosineDistance: ");var u=Cn(1).sub(a.mul(i).sum(n,!0));return Uc(u,s,o)}}),zc=mn({hingeLoss_:function(t,e,n,r){void 0===r&&(r=Pc.SUM_BY_NONZERO_WEIGHTS);var o=rn(t,"labels","hingeLoss"),a=rn(e,"predictions","hingeLoss"),i=null;null!=n&&(i=rn(n,"weights","hingeLoss")),p(o.shape,a.shape,"Error in hingeLoss: ");var s=Cn(1);o=Cn(2).mul(o).sub(s);var u=s.sub(o.mul(a)).relu();return Uc(u,i,r)}}),Gc=mn({huberLoss_:function(t,e,n,r,o){void 0===r&&(r=1),void 0===o&&(o=Pc.SUM_BY_NONZERO_WEIGHTS);var a=rn(t,"labels","huberLoss"),i=rn(e,"predictions","huberLoss"),s=null;null!=n&&(s=rn(n,"weights","huberLoss")),p(a.shape,i.shape,"Error in huberLoss: ");var u=Cn(r),l=i.sub(a).abs(),c=Uu(l,u),h=l.sub(c),f=Cn(.5).mul(c.square()).add(u.mul(h));return Uc(f,s,o)}}),Hc=mn({logLoss_:function(t,e,n,r,o){void 0===r&&(r=1e-7),void 0===o&&(o=Pc.SUM_BY_NONZERO_WEIGHTS);var a=rn(t,"labels","logLoss"),i=rn(e,"predictions","logLoss"),s=null;null!=n&&(s=rn(n,"weights","logLoss")),p(a.shape,i.shape,"Error in logLoss: ");var u=Cn(1),l=Cn(r),c=a.mul(i.add(l).log()).neg().sub(u.sub(a).mul(u.sub(i).add(l).log()));return Uc(c,s,o)}}),qc=mn({meanSquaredError_:function(t,e,n,r){void 0===r&&(r=Pc.SUM_BY_NONZERO_WEIGHTS);var o=rn(t,"labels","meanSquaredError"),a=rn(e,"predictions","meanSquaredError"),i=null;null!=n&&(i=rn(n,"weights","meanSquaredError")),p(o.shape,a.shape,"Error in meanSquaredError: ");var s=o.squaredDifference(a);return Uc(s,i,r)}}),$c=mn({sigmoidCrossEntropy_:function(t,e,n,r,o){void 0===r&&(r=0),void 0===o&&(o=Pc.SUM_BY_NONZERO_WEIGHTS);var a=rn(t,"multiClassLabels","sigmoidCrossEntropy"),i=rn(e,"logits","sigmoidCrossEntropy"),s=null;if(null!=n&&(s=rn(n,"weights","sigmoidCrossEntropy")),p(a.shape,i.shape,"Error in sigmoidCrossEntropy: "),r>0){var u=Cn(r),l=Cn(1),c=Cn(.5);a=a.mul(l.sub(u)).add(c.mul(u))}var h=function(t,e){var n=rn(t,"labels","sigmoidCrossEntropyWithLogits"),r=rn(e,"logits","sigmoidCrossEntropyWithLogits");p(n.shape,r.shape,"Error in sigmoidCrossEntropyWithLogits: ");var o=r.relu(),a=r.mul(n),i=r.abs().neg().exp().log1p();return o.sub(a).add(i)}(a,i);return Uc(h,s,o)}}),Kc=mn({softmaxCrossEntropy_:function(t,e,n,r,o){void 0===r&&(r=0),void 0===o&&(o=Pc.SUM_BY_NONZERO_WEIGHTS);var a=rn(t,"onehotLabels","softmaxCrossEntropy"),i=rn(e,"logits","softmaxCrossEntropy"),s=null;if(null!=n&&(s=rn(n,"weights","softmaxCrossEntropy")),p(a.shape,i.shape,"Error in softmaxCrossEntropy: "),r>0){var u=Cn(r),l=Cn(1),c=Cn(a.shape[1]);a=a.mul(l.sub(u)).add(u.div(c))}var h=function(t,e,n){if(void 0===n&&(n=-1),-1===n&&(n=e.rank-1),n!==e.rank-1)throw Error("Softmax cross entropy along a non-last dimension is not yet supported. Labels / logits was rank "+e.rank+" and dim was "+n);return Xr(function(t,e,r){var o=e.logSumExp([n],!0),a=e.toFloat().sub(o);return r([t,a]),{value:a.mul(t).neg().sum([n]),gradFunc:function(t,e){var r=e[0],o=e[1],a=ln(t.shape,[n]);return[t.reshape(a).mul(r.toFloat().sub(o.exp())),t.reshape(a).mul(o.exp().sub(r.toFloat()))]}}})(t,e)}(a,i);return Uc(h,s,o)}}),jc=Object.freeze({get Reduction(){return Pc},absoluteDifference:Wc,computeWeightedLoss:Uc,cosineDistance:Vc,hingeLoss:zc,huberLoss:Gc,logLoss:Hc,meanSquaredError:qc,sigmoidCrossEntropy:$c,softmaxCrossEntropy:Kc});function Xc(t,e){return void 0===e&&(e=!1),kt.tidy(function(){if(2!==t.shape.length)throw new Error("qr2d() requires a 2D Tensor, but got a "+t.shape.length+"D Tensor.");for(var n=t.shape[0],r=t.shape[1],o=ur(n),a=t.clone(),i=Rn([[1]],[1,1]),s=i.clone(),u=n>=r?r:n,l=function(t){var e,u=a,l=s,c=o;e=kt.tidy(function(){var e=a.slice([t,t],[n-t,1]),u=e.norm(),l=a.slice([t,t],[1,1]),c=Rn([[-1]]).where(l.greater(0),Rn([[1]])),h=l.sub(c.mul(u)),p=e.div(h);s=1===p.shape[0]?i.clone():i.concat(p.slice([1,0],[p.shape[0]-1,p.shape[1]]),0);var f=c.matMul(h).div(u).neg(),d=a.slice([t,0],[n-t,r]),v=f.mul(s);if(0===t)a=d.sub(v.matMul(s.transpose().matMul(d)));else{var m=d.sub(v.matMul(s.transpose().matMul(d)));a=a.slice([0,0],[t,r]).concat(m,0)}var g=o.slice([0,t],[n,o.shape[1]-t]);if(0===t)o=g.sub(g.matMul(s).matMul(v.transpose()));else{var y=g.sub(g.matMul(s).matMul(v.transpose()));o=o.slice([0,0],[n,t]).concat(y,1)}return[s,a,o]}),s=e[0],a=e[1],o=e[2],ze([u,l,c])},c=0;cr&&(o=o.slice([0,0],[n,r]),a=a.slice([0,0],[r,r])),[o,a]})}var Yc=mn({gramSchmidt_:function(t){var e;if(Array.isArray(t)){e=!1,h(null!=t&&t.length>0,function(){return"Gram-Schmidt process: input must not be null, undefined, or empty"});for(var n=t[0].shape[0],r=function(e){h(t[e].shape[0]===n,function(){return"Gram-Schmidt: Non-unique lengths found in the input vectors: ("+t[e].shape[0]+" vs. "+n+")"})},o=1;o0)for(var n=0;n= 2, but got rank "+t.rank);if(2===t.rank)return Xc(t,e);var n=t.shape.slice(0,t.shape.length-2).reduce(function(t,e){return t*e}),r=kr(t.reshape([n,t.shape[t.shape.length-2],t.shape[t.shape.length-1]]),0),o=[],a=[];return r.forEach(function(t){var n=Xc(t,e),r=n[0],i=n[1];o.push(r),a.push(i)}),[Er(o,0).reshape(t.shape),Er(a,0).reshape(t.shape)]}}),Jc=Object.freeze({gramSchmidt:Yc,qr:Qc});function Zc(t,e,n,r,o){null==r&&(r=.5),null==o&&(o=Number.NEGATIVE_INFINITY);var a=t.shape[0];return n=Math.min(n,a),h(0<=r&&r<=1,function(){return"iouThreshold must be in [0, 1], but was '"+r+"'"}),h(2===t.rank,function(){return"boxes must be a 2D tensor, but was of rank '"+t.rank+"'"}),h(4===t.shape[1],function(){return"boxes must have 4 columns, but 2nd dimension was "+t.shape[1]}),h(1===e.rank,function(){return"scores must be a 1D tensor"}),h(e.shape[0]===a,function(){return"scores has incompatible shape with boxes. Expected "+a+", but was "+e.shape[0]}),{maxOutputSize:n,iouThreshold:r,scoreThreshold:o}}var th=mn({resizeBilinear_:function(t,e,n){void 0===n&&(n=!1);var r=rn(t,"images","resizeBilinear");h(3===r.rank||4===r.rank,function(){return"Error in resizeBilinear: x must be rank 3 or 4, but got rank "+r.rank+"."}),h(2===e.length,function(){return"Error in resizeBilinear: new shape must 2D, but got shape "+e+"."});var o=r,a=!1;3===r.rank&&(a=!0,o=r.as4D(1,r.shape[0],r.shape[1],r.shape[2]));var i=e[0],s=e[1],u=kt.runKernel(function(t,e){return e([o]),t.resizeBilinear(o,i,s,n)},{batchImages:o},function(t,e){return{batchImages:function(){return kt.runKernel(function(r){return r.resizeBilinearBackprop(t,e[0],n)},{})}}});return a?u.as3D(u.shape[1],u.shape[2],u.shape[3]):u}}),eh=mn({resizeNearestNeighbor_:function(t,e,n){void 0===n&&(n=!1);var r=rn(t,"images","resizeNearestNeighbor");h(3===r.rank||4===r.rank,function(){return"Error in resizeNearestNeighbor: x must be rank 3 or 4, but got rank "+r.rank+"."}),h(2===e.length,function(){return"Error in resizeNearestNeighbor: new shape must 2D, but got shape "+e+"."}),h("float32"===r.dtype||"int32"===r.dtype,function(){return"`images` must have `int32` or `float32` as dtype"});var o=r,a=!1;3===r.rank&&(a=!0,o=r.as4D(1,r.shape[0],r.shape[1],r.shape[2]));var i=e[0],s=e[1],u=kt.runKernel(function(t,e){return e([o]),t.resizeNearestNeighbor(o,i,s,n)},{batchImages:o},function(t,e){return{batchImages:function(){return kt.runKernel(function(r){return r.resizeNearestNeighborBackprop(t,e[0],n)},{})}}});return a?u.as3D(u.shape[1],u.shape[2],u.shape[3]):u}}),nh=mn({nonMaxSuppression_:function(t,e,n,r,o){void 0===r&&(r=.5),void 0===o&&(o=Number.NEGATIVE_INFINITY);var a=rn(t,"boxes","nonMaxSuppression"),i=rn(e,"scores","nonMaxSuppression"),s=Zc(a,i,n,r,o);return n=s.maxOutputSize,r=s.iouThreshold,o=s.scoreThreshold,kt.runKernel(function(t){return t.nonMaxSuppression(a,i,n,r,o)},{$boxes:a})}}),rh=function(t,e,o,a,i){return void 0===a&&(a=.5),void 0===i&&(i=Number.NEGATIVE_INFINITY),n(this,void 0,void 0,function(){var n,s,u,l,c,h,p;return r(this,function(r){switch(r.label){case 0:return n=rn(t,"boxes","nonMaxSuppressionAsync"),s=rn(e,"scores","nonMaxSuppressionAsync"),u=Zc(n,s,o,a,i),o=u.maxOutputSize,a=u.iouThreshold,i=u.scoreThreshold,[4,Promise.all([n.data(),s.data()])];case 1:return l=r.sent(),c=l[0],h=l[1],p=Io(c,h,o,a,i),n!==t&&n.dispose(),s!==e&&s.dispose(),[2,p]}})})},oh=mn({cropAndResize_:function(t,e,n,r,o,a){var i=rn(t,"image","cropAndResize","float32"),s=rn(e,"boxes","cropAndResize","float32"),u=rn(n,"boxInd","cropAndResize","int32");o=o||"bilinear",a=a||0;var l=s.shape[0];return h(4===i.rank,function(){return"Error in cropAndResize: image must be rank 4,but got rank "+i.rank+"."}),h(2===s.rank&&4===s.shape[1],function(){return"Error in cropAndResize: boxes must be have size ["+l+",4] but had shape "+s.shape+"."}),h(1===u.rank&&u.shape[0]===l,function(){return"Error in cropAndResize: boxInd must be have size ["+l+"] but had shape "+s.shape+"."}),h(2===r.length,function(){return"Error in cropAndResize: cropSize must be of length 2, but got length "+r.length+"."}),h(r[0]>=1&&r[1]>=1,function(){return"cropSize must be atleast [1,1], but was "+r}),h("bilinear"===o||"nearest"===o,function(){return"method must be bilinear or nearest, but was "+o}),kt.runKernel(function(t,e){return t.cropAndResize(i,s,u,r,o,a)},{$image:i,$boxes:s})}}),ah=Object.freeze({resizeBilinear:th,resizeNearestNeighbor:eh,nonMaxSuppression:nh,nonMaxSuppressionAsync:rh,cropAndResize:oh});var ih=mn({matMul_:function(t){var e,n=t.a,r=t.b,o=t.transposeA,a=void 0!==o&&o,i=t.transposeB,s=void 0!==i&&i,u=t.bias,l=t.activation,c=void 0===l?"linear":l,p=t.preluActivationWeights,f=rn(n,"a","fused matMul"),d=rn(r,"b","fused matMul");e=xt(f,d),f=e[0],d=e[1];var g=a?f.shape[f.rank-2]:f.shape[f.rank-1],y=s?d.shape[d.rank-1]:d.shape[d.rank-2],x=a?f.shape[f.rank-1]:f.shape[f.rank-2],b=s?d.shape[d.rank-2]:d.shape[d.rank-1],w=f.shape.slice(0,-2),C=d.shape.slice(0,-2),E=v(w),R=v(C);h(f.rank>=2&&d.rank>=2&&f.rank===d.rank,function(){return"Error in fused matMul: inputs must have the same rank of at least 2, got ranks "+f.rank+" and "+d.rank+"."}),h(m(w,C),function(){return"Error in fused matMul: outer dimensions ("+w+") and ("+C+") of Tensors with shapes "+f.shape+" and "+d.shape+" must match."}),h(g===y,function(){return"Error in fused matMul: inner shapes ("+g+") and ("+y+") of Tensors with shapes "+f.shape+" and "+d.shape+" and transposeA="+a+" and transposeB="+s+" must match."});var I,k,N=f.shape.slice(0,-2).concat([x,b]),S=a?f.as3D(E,g,x):f.as3D(E,x,g),A=s?d.as3D(R,b,y):d.as3D(R,y,b);null!=u&&ro(N,(I=xt(I=rn(u,"bias","fused matMul"),f)[0]).shape),null!=p&&(k=rn(p,"prelu weights","fused matMul"));var T={$a:S,$b:A};return null!=u&&(T.$bias=I),null!=p&&(T.$preluActivationWeights=k),kt.runKernel(function(t,e){var n=t.fusedBatchMatMul({a:S,b:A,transposeA:a,transposeB:s,bias:I,activation:c,preluActivationWeights:k});return e([S,A,n]),n},T,function(t,e){var n,r=e[0],o=e[1],i=e[2];if(null==c||"linear"===c)n=t;else{if("relu"!==c)throw new Error("Gradient for activation "+c+" has not been implemented yet.");n=t.mul(i.step())}var l={};return null!=u&&(l={$bias:function(){var t=n,e=no(I.shape,n.shape);return e.length>0&&(t=t.sum(e)),t.reshape(I.shape)}}),a||s?!a&&s?Object.assign({$a:function(){return n.matMul(o,!1,!1)},$b:function(){return n.matMul(r,!0,!1)}},l):a&&!s?Object.assign({$a:function(){return o.matMul(n,!1,!0)},$b:function(){return r.matMul(n,!1,!1)}},l):Object.assign({$a:function(){return o.matMul(n,!0,!0)},$b:function(){return n.matMul(r,!0,!0)}},l):Object.assign({$a:function(){return n.matMul(o,!1,!0)},$b:function(){return r.matMul(n,!0,!1)}},l)}).reshape(N)}}),sh=mn({conv2d_:function(t){var e=t.x,n=t.filter,r=t.strides,o=t.pad,a=t.dataFormat,i=void 0===a?"NHWC":a,s=t.dilations,u=void 0===s?[1,1]:s,l=t.dimRoundingMode,c=t.bias,p=t.activation,f=void 0===p?"linear":p,d=t.preluActivationWeights,v=rn(e,"x","conv2d"),m=rn(n,"filter","conv2d"),y=v,x=!1;3===v.rank&&(x=!0,y=v.as4D(1,v.shape[0],v.shape[1],v.shape[2])),h(4===y.rank,function(){return"Error in fused conv2d: input must be rank 4, but got rank "+y.rank+"."}),h(4===m.rank,function(){return"Error in fused conv2d: filter must be rank 4, but got rank "+m.rank+"."}),null!=l&&h(g(o),function(){return"Error in fused conv2d: pad must be an integer when using, dimRoundingMode "+l+" but got pad "+o+"."}),h(y.shape[3]===m.shape[2],function(){return"Error in conv2d: depth of input ("+y.shape[3]+") must match input depth for filter "+m.shape[2]+"."}),h(vo(r,u),function(){return"Error in conv2D: Either strides or dilations must be 1. Got strides "+r+" and dilations '"+u+"'"}),h("NHWC"===i,function(){return"Error in conv2d: got dataFormat of "+i+" but only NHWC is currently supported."});var b,w,C=io(y.shape,m.shape,r,u,o,l);null!=c&&(b=xt(b=rn(c,"bias","fused conv2d"),v)[0],ro(C.outShape,b.shape)),null!=d&&(w=rn(d,"prelu weights","fused conv2d"));var E={x:y,$filter:m};null!=c&&(E.$bias=b),null!=d&&(E.$preluActivationWeights=w);var R=kt.runKernel(function(t,e){var n=t.fusedConv2d({input:y,filter:m,convInfo:C,bias:b,activation:f,preluActivationWeights:w});return e([m,y,n]),n},E,function(t,e){var n,a=e,i=a[0],s=a[1],l=a[2];if(null==f||"linear"===f)n=t;else{if("relu"!==f)throw new Error("Gradient for activation "+f+" has not been implemented yet.");n=t.mul(l.step())}h(fo(u),function(){return"Error in gradient of fused conv2D: dilation rates greater than 1 are not yet supported in gradients. Got dilations '"+u+"'"});var p={};return null!=c&&(p={$bias:function(){var t=n,e=no(b.shape,n.shape);return e.length>0&&(t=t.sum(e)),t.reshape(b.shape)}}),Object.assign({x:function(){return Cl(s.shape,n,i,r,o)},$filter:function(){return wl(s,n,i.shape,r,o)}},p)});return x?R.as3D(R.shape[1],R.shape[2],R.shape[3]):R}}),uh=mn({depthwiseConv2d_:function(t){var e=t.x,n=t.filter,r=t.strides,o=t.pad,a=(t.dataFormat,t.dilations),i=void 0===a?[1,1]:a,s=t.dimRoundingMode,u=t.bias,l=t.activation,c=void 0===l?"linear":l,p=t.preluActivationWeights,f=rn(e,"x","depthwiseConv2d"),d=rn(n,"filter","depthwiseConv2d"),v=f,m=!1;3===f.rank&&(m=!0,v=f.as4D(1,f.shape[0],f.shape[1],f.shape[2])),h(4===v.rank,function(){return"Error in fused depthwiseConv2d: input must be rank 4, but got rank "+v.rank+"."}),h(4===d.rank,function(){return"Error in fused depthwiseConv2d: filter must be rank 4, but got rank "+d.rank+"."}),h(v.shape[3]===d.shape[2],function(){return"Error in fused depthwiseConv2d: number of input channels ("+v.shape[3]+") must match the inChannels dimension in filter "+d.shape[2]+"."}),null==i&&(i=[1,1]),h(vo(r,i),function(){return"Error in fused depthwiseConv2d: Either strides or dilations must be 1. Got strides "+r+" and dilations '"+i+"'"}),null!=s&&h(g(o),function(){return"Error in fused depthwiseConv2d: pad must be an integer when using dimRoundingMode "+s+" but got pad "+o+"."});var y,x,b=io(v.shape,d.shape,r,i,o,s,!0);null!=u&&(y=xt(y=rn(u,"bias","fused conv2d"),f)[0],ro(b.outShape,y.shape)),null!=p&&(x=rn(p,"prelu weights","fused depthwiseConv2d"));var w={x:v,$filter:d};null!=u&&(w.$bias=y),null!=p&&(w.$preluActivationWeights=x);var C=kt.runKernel(function(t,e){var n=t.fusedDepthwiseConv2D({input:v,filter:d,convInfo:b,bias:y,activation:c,preluActivationWeights:x});return e([v,d,n]),n},w,function(t,e){h(fo(i),function(){return"Error in gradient of fused depthwiseConv2d: dilation rates greater than 1 are not yet supported. Got dilations '"+i+"'"});var n,r=e[0],o=e[1],a=e[2];if(null==c||"linear"===c)n=t;else{if("relu"!==c)throw new Error("Gradient for activation "+c+" has not been implemented yet.");n=t.mul(a.step())}var s={};return null!=u&&(s={$bias:function(){var t=n,e=no(y.shape,n.shape);return e.length>0&&(t=t.sum(e)),t.reshape(y.shape)}}),Object.assign({x:function(){return Rl(r.shape,n,o,b)},$filter:function(){return Il(r,n,o.shape,b)}},s)});return m?C.as3D(C.shape[1],C.shape[2],C.shape[3]):C}}),lh=Object.freeze({matMul:ih,conv2d:sh,depthwiseConv2d:uh}),ch=Object.freeze({image:ah,linalg:Jc,losses:jc,spectral:kc,fused:lh,signal:Bc,conv1d:yl,conv2d:xl,conv3d:bl,depthwiseConv2d:El,separableConv2d:kl,conv2dTranspose:Nl,conv3dTranspose:Sl,op:mn,batchNormalization2d:gu,batchNormalization3d:yu,batchNormalization4d:xu,batchNormalization:bu,batchNorm:wu,batchNorm2d:Cu,batchNorm3d:Eu,batchNorm4d:Ru,booleanMaskAsync:dl,complex:gn,real:yn,imag:xn,concat:Bn,concat1d:Pn,concat2d:Ln,concat3d:Wn,concat4d:Un,split:Vn,matMul:Al,dot:Tl,outerProduct:Dl,reverse:_l,reverse1d:Ol,reverse2d:Fl,reverse3d:Ml,reverse4d:Bl,maxPool:Wl,avgPool:Ul,pool:Vl,maxPool3d:zl,avgPool3d:Gl,slice:Hl,slice1d:ql,slice2d:$l,slice3d:Kl,slice4d:jl,abs:Ts,acos:Ds,acosh:_s,asin:Os,asinh:Fs,atan:Ms,atanh:Bs,ceil:Ps,clipByValue:Ls,cos:Ws,cosh:Us,erf:Vs,exp:zs,expm1:Gs,floor:Hs,log:qs,log1p:$s,logSigmoid:Ks,neg:js,reciprocal:Xs,round:Ys,rsqrt:Qs,sigmoid:Js,sign:Zs,isNaN:tu,isInf:eu,isFinite:nu,sin:ru,sinh:ou,softplus:au,sqrt:iu,square:su,step:uu,tan:lu,tanh:cu,all:Yl,any:Ql,argMax:Jl,argMin:Zl,logSumExp:tc,max:ec,mean:nc,min:rc,moments:oc,sum:ac,prod:ic,equal:Ju,equalStrict:Zu,greater:tl,greaterEqual:el,greaterEqualStrict:nl,greaterStrict:rl,less:ol,lessEqual:al,lessEqualStrict:il,lessStrict:sl,notEqual:ul,notEqualStrict:ll,add:Du,addN:_u,addStrict:Ou,atan2:Fu,div:Mu,divStrict:Bu,floorDiv:Pu,maximum:Lu,maximumStrict:Wu,minimum:Uu,minimumStrict:Vu,mod:zu,modStrict:Gu,mul:Hu,mulStrict:qu,pow:$u,powStrict:Ku,squaredDifference:ju,squaredDifferenceStrict:Xu,sub:Yu,subStrict:Qu,elu:sc,leakyRelu:uc,prelu:lc,relu:cc,relu6:hc,selu:pc,logicalAnd:Iu,logicalNot:ku,logicalOr:Nu,logicalXor:Su,where:Au,whereAsync:Tu,buffer:tr,print:er,batchToSpaceND:nr,cast:rr,clone:or,cumsum:ar,depthToSpace:ir,expandDims:sr,eye:ur,multinomial:lr,oneHot:cr,pad:hr,pad1d:pr,pad2d:fr,pad3d:dr,pad4d:vr,rand:mr,randomNormal:gr,randomGamma:yr,randomUniform:xr,reshape:br,spaceToBatchND:wr,squeeze:Cr,stack:Er,tile:Rr,truncatedNormal:Ir,unstack:kr,setdiff1dAsync:Nr,fill:Dn,linspace:_n,ones:An,range:On,scalar:Cn,tensor:bn,tensor1d:En,tensor2d:Rn,tensor3d:In,tensor4d:kn,tensor5d:Nn,tensor6d:Sn,zeros:Tn,onesLike:Fn,zerosLike:Mn,transpose:fc,softmax:Qr,logSoftmax:Jr,localResponseNormalization:dc,norm:vc,gather:pl,unsortedSegmentSum:fl,basicLSTMCell:mc,multiRNNCell:gc,movingAverage:yc,stridedSlice:xc,topk:bc,scatterND:wc,fft:Cc,ifft:Ec,rfft:Rc,irfft:Ic,sparseToDense:Nc,gatherND:Sc,diag:Ac,dropout:Tc,hannWindow:_c,hammingWindow:Oc,frame:Fc,stft:Mc,inTopKAsync:Lc});function hh(t,e,n,r){if("linear"===n)return t.linear(e);if("relu"===n)return t.relu(e);if("elu"===n)return t.elu(e);if("relu6"===n)return t.relu6(e);if("prelu"===n)return t.prelu(e,r);throw new Error("Activation "+n+" has not been implemented for the CPU backend.")}var ph=function(){function t(){if(this.blockSize=48,this.firstUse=!0,a().get("IS_BROWSER")){var t="undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(300,150):"undefined"!=typeof document?document.createElement("canvas"):null;null!==t&&(this.fromPixels2DContext=t.getContext("2d"))}this.data=new Zr(this,kt)}return t.prototype.register=function(t,e,n){if(this.firstUse&&(this.firstUse=!1,a().get("IS_NODE")&&tn("\n============================\nHi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.\n============================\n")),this.data.has(t))throw new Error("Data buffer is already registered");this.data.set(t,{dtype:n})},t.prototype.write=function(t,e){if(null==e)throw new Error("MathBackendCPU.write(): values can not be null");this.data.get(t).values=e},t.prototype.fromPixels=function(t,e){if(null==t)throw new Error("pixels passed to tf.browser.fromPixels() can not be null");var n,r,o=t.data instanceof Uint8Array,i="undefined"!=typeof ImageData&&t instanceof ImageData,s="undefined"!=typeof HTMLVideoElement&&t instanceof HTMLVideoElement,u="undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement,l=s?[t.videoWidth,t.videoHeight]:[t.width,t.height],c=l[0],h=l[1];if(a().get("IS_NODE")&&null==t.getContext)throw new Error("When running in node, pixels must be an HTMLCanvasElement like the one returned by the `canvas` npm package");if(null!=t.getContext)n=t.getContext("2d").getImageData(0,0,c,h).data;else if(i||o)n=t.data;else{if(!u&&!s)throw new Error("pixels passed to tf.browser.fromPixels() must be either an HTMLVideoElement, HTMLImageElement, HTMLCanvasElement, ImageData or {data: Uint32Array, width: number, height: number}, but was "+t.constructor.name);if(null==this.fromPixels2DContext)throw new Error("Can't read pixels from HTMLImageElement outside the browser.");this.fromPixels2DContext.canvas.width=c,this.fromPixels2DContext.canvas.height=h,this.fromPixels2DContext.drawImage(t,0,0,c,h),n=this.fromPixels2DContext.getImageData(0,0,c,h).data}if(4===e)r=new Int32Array(n);else{var p=c*h;r=new Int32Array(p*e);for(var f=0;fp&&(p=m,f=d)}u[c]=f}return i},t.prototype.cumsum=function(t,e,n,r){if(this.assertNotComplex(t,"cumsum"),e!==t.rank-1)throw new Error("backend.cumsum in CPU expects an inner-most axis="+(t.rank-1)+" but got axis="+e);for(var o=gt(t.dtype,"int32"),a=Tn(t.shape,o),i=this.readSync(a.dataId),s=this.readSync(t.dataId),u=t.shape[t.rank-1],l=r?function(t,e){return t+u-e-1}:function(t,e){return t+e},c=0;ce?1:0})},t.prototype.greaterEqual=function(t,e){return this.assertNotComplex([t,e],"greaterEqual"),this.broadcastedBinaryOp(t,e,"bool",function(t,e){return t>=e?1:0})},t.prototype.logicalNot=function(t){this.assertNotComplex(t,"logicalNot");for(var e=this.readSync(t.dataId),n=new Uint8Array(e.length),r=0;r1||1===e.rank?1:v(e.shape.slice(1)),c=0;c=0&&e>=0?n:(n+e)%e})},t.prototype.max=function(t,e){this.assertNotComplex(t,"max"),cn("max",e,t.rank);for(var n=un(t.shape,e),r=n[0],o=n[1],a=Tn(r,t.dtype),i=v(o),s=this.readSync(a.dataId),u=this.readSync(t.dataId),l=0;lh&&(h=f)}s[l]=h}return a},t.prototype.maximum=function(t,e){return this.assertNotComplex([t,e],"maximum"),this.broadcastedBinaryOp(t,e,t.dtype,function(t,e){return Math.max(t,e)})},t.prototype.all=function(t,e){this.assertNotComplex(t,"all"),cn("all",e,t.rank);for(var n=un(t.shape,e),r=n[0],o=n[1],a=Tn(r,t.dtype),i=v(o),s=this.readSync(a.dataId),u=this.readSync(t.dataId),l=0;l0?n[r]=1:n[r]=0;return ut.make(t.shape,{values:n})},t.prototype.isNaN=function(t){this.assertNotComplex(t,"x");for(var e=this.readSync(t.dataId),n=new Uint8Array(e.length),r=0;r.5?n[r]=Math.ceil(e[r]):n[r]=o%2==0?o:o+1}return ut.make(t.shape,{values:n})},t.prototype.exp=function(t){this.assertNotComplex(t,"exp");for(var e=this.readSync(t.dataId),n=new Float32Array(e.length),r=0;r=0?o:Math.exp(o)-1}return ut.make(t.shape,{values:e})},t.prototype.eluDer=function(t,e){this.assertNotComplex([t,e],"eluDer");for(var n=new Float32Array(e.size),r=this.readSync(e.dataId),o=this.readSync(t.dataId),a=0;a=1?o[a]:o[a]*(i+1)}return ut.make(e.shape,{values:n})},t.prototype.selu=function(t){this.assertNotComplex(t,"selu");for(var e=Yi,n=Qi,r=new Float32Array(t.size),o=this.readSync(t.dataId),a=0;a=0?n*i:e*(Math.exp(i)-1)}return ut.make(t.shape,{values:r})},t.prototype.clip=function(t,e,n){this.assertNotComplex(t,"clip");for(var r=new Float32Array(t.size),o=this.readSync(t.dataId),a=0;an?n:i-e,i=r[o]0?1:e}return ut.make(t.shape,{values:n})},t.prototype.fusedConv2d=function(t){var e=t.input,n=t.filter,r=t.convInfo,o=t.bias,a=t.activation,i=t.preluActivationWeights,s=this.conv2d(e,n,r);return o&&(s=this.add(s,o)),a&&(s=hh(this,s,a,i)),s},t.prototype.conv2d=function(t,e,n){this.assertNotComplex([t,e],"conv2d");for(var r=n.filterHeight,o=n.filterWidth,a=n.dilationHeight,i=n.dilationWidth,s=n.padInfo.left,u=n.padInfo.top,l="channelsLast"===n.dataFormat,c=tr(n.outShape,t.dtype),h=t.strides[0],p=l?t.strides[1]:t.strides[2],f=l?t.strides[2]:1,d=l?1:t.strides[1],v=c.strides[0],m=l?c.strides[1]:c.strides[2],g=l?c.strides[2]:1,y=l?1:c.strides[1],x=this.readSync(t.dataId),b=this.readSync(e.dataId),w=c.values,C=0;C=n.inHeight))for(var T=S*e.strides[0],D=E+A*p,_=0;_=n.inWidth))for(var P=D+B*f,L=T+M*e.strides[1],W=0;W=n.inDepth))for(var R=C*e.strides[0],I=g+E*t.strides[1],k=0;k=n.inHeight))for(var D=R+A*e.strides[1],_=I+T*t.strides[2],O=0;O=n.inWidth))for(var L=D+B*e.strides[2],W=_+P*n.inChannels,U=L,V=0;V=n.inHeight))for(var C=b*e.strides[0],E=v+w*t.strides[1],R=0;R=n.inWidth))for(var A=C+N*e.strides[1],T=E+S*n.inChannels,D=I,_=A,O=0;OD?D=P:"avg"===n&&(_+=P,O++)}if(isNaN(D))break}d[k+N*g+w]="avg"===n?_/O:D}return f.toTensor()},t.prototype.maxPool=function(t,e){return this.pool(t,e,"max")},t.prototype.maxPoolPositions=function(t,e){for(var n=tr(e.outShape,"int32"),r=e.strideHeight,o=e.strideWidth,a=e.dilationHeight,i=e.dilationWidth,s=e.effectiveFilterHeight,u=e.effectiveFilterWidth,l=e.padInfo.top,c=e.padInfo.left,h=this.bufferSync(t),p=0;pC&&(C=S,E=I*u+N)}n.set(E,p,d,y,f)}}return n.toTensor()},t.prototype.maxPoolBackprop=function(t,e,n,r){this.assertNotComplex([e,n],"maxPoolBackprop");for(var o=this.maxPoolPositions(e,r),a=r.strideHeight,i=r.strideWidth,s=r.dilationHeight,u=r.dilationWidth,l=r.effectiveFilterHeight,c=r.effectiveFilterWidth,h=c-1-r.padInfo.left,p=l-1-r.padInfo.top,f=tr(e.shape,"float32"),d=this.bufferSync(o),v=this.bufferSync(t),m=0;m=r.outHeight||Math.floor(R)!==R))for(var I=0;I=r.outWidth||Math.floor(k)!==k)){var N=l*c-1-d.get(m,R,k,g)===E*c+I?1:0;if(0!==N)C+=v.get(m,R,k,g)*N}}}f.set(C,m,y,x,g)}return f.toTensor()},t.prototype.avgPoolBackprop=function(t,e,n){this.assertNotComplex([t,e],"avgPoolBackprop");for(var r=n.strideHeight,o=n.strideWidth,a=n.filterHeight,i=n.filterWidth,s=n.dilationHeight,u=n.dilationWidth,l=n.effectiveFilterHeight,c=n.effectiveFilterWidth,h=c-1-n.padInfo.left,p=l-1-n.padInfo.top,f=tr(e.shape,"float32"),d=1/(a*i),v=this.bufferSync(t),m=0;m=n.outHeight||Math.floor(R)!==R))for(var I=0;I=n.outWidth||Math.floor(k)!==k))C+=v.get(m,R,k,g)}}f.set(C*d,m,y,x,g)}return f.toTensor()},t.prototype.pool3d=function(t,e,n){this.assertNotComplex(t,"pool3d");for(var r=e.strideDepth,o=e.strideHeight,a=e.strideWidth,i=e.dilationDepth,s=e.dilationHeight,u=e.dilationWidth,l=e.effectiveFilterDepth,c=e.effectiveFilterHeight,h=e.effectiveFilterWidth,p=e.padInfo.front,f=e.padInfo.top,d=e.padInfo.left,v="max"===n?Number.NEGATIVE_INFINITY:Number.POSITIVE_INFINITY,m=this.readSync(t.dataId),g=tr(e.outShape,t.dtype),y=g.values,x=e.outShape[1]*e.outShape[2]*e.outShape[3]*e.outShape[4],b=e.outShape[2]*e.outShape[3]*e.outShape[4],w=e.outShape[3]*e.outShape[4],C=e.outShape[4],E=0;Ez?z=Y:"avg"===n&&(G+=Y,H++),isNaN(z))break}if(isNaN(z))break}if(isNaN(z))break}y[V+k]="avg"===n?G/H:z}}}return g.toTensor()},t.prototype.avgPool3d=function(t,e){return this.assertNotComplex(t,"avgPool3d"),this.pool3d(t,e,"avg").toFloat()},t.prototype.avgPool3dBackprop=function(t,e,n){this.assertNotComplex([t,e],"avgPool3dBackprop");for(var r=n.strideDepth,o=n.strideHeight,a=n.strideWidth,i=n.filterDepth,s=n.filterHeight,u=n.filterWidth,l=n.dilationDepth,c=n.dilationHeight,h=n.dilationWidth,p=n.effectiveFilterDepth,f=n.effectiveFilterHeight,d=n.effectiveFilterWidth,v=p-1-n.padInfo.front,m=d-1-n.padInfo.left,g=f-1-n.padInfo.top,y=tr(e.shape,"float32"),x=1/(i*s*u),b=this.bufferSync(t),w=0;w=n.outDepth||Math.floor(D)!==D))for(var _=0;_=n.outHeight||Math.floor(O)!==O))for(var F=0;F=n.outWidth||Math.floor(M)!==M))A+=b.get(w,D,O,M,C)}}}y.set(A*x,w,E,R,I,C)}return y.toTensor()},t.prototype.maxPool3d=function(t,e){return this.assertNotComplex(t,"maxPool3d"),this.pool3d(t,e,"max").toFloat()},t.prototype.maxPool3dPositions=function(t,e){for(var n=tr(e.outShape,"int32"),r=e.strideDepth,o=e.strideHeight,a=e.strideWidth,i=e.dilationDepth,s=e.dilationHeight,u=e.dilationWidth,l=e.effectiveFilterDepth,c=e.effectiveFilterHeight,h=e.effectiveFilterWidth,p=e.padInfo.front,f=e.padInfo.top,d=e.padInfo.left,v=this.bufferSync(t),m=0;m=T&&(T=L,D=O*c*h+M*c+P)}n.set(D,m,y,C,k,g)}}}return n.toTensor()},t.prototype.maxPool3dBackprop=function(t,e,n,r){this.assertNotComplex([e,n],"maxPool3dBackprop");for(var o=this.maxPool3dPositions(e,r),a=r.strideDepth,i=r.strideHeight,s=r.strideWidth,u=r.dilationDepth,l=r.dilationHeight,c=r.dilationWidth,h=r.effectiveFilterDepth,p=r.effectiveFilterHeight,f=r.effectiveFilterWidth,d=h-1-r.padInfo.front,v=f-1-r.padInfo.left,m=p-1-r.padInfo.top,g=tr(e.shape,"float32"),y=this.bufferSync(o),x=this.bufferSync(t),b=0;b=r.outDepth||Math.floor(T)!==T))for(var D=0;D=r.outHeight||Math.floor(_)!==_))for(var O=0;O=r.outWidth||Math.floor(F)!==F)){var M=h*p*f-1-y.get(b,T,_,F,w)===A*p*f+D*f+O?1:0;if(0!==M)S+=x.get(b,T,_,F,w)*M}}}}g.set(S,b,C,E,R,w)}return g.toTensor()},t.prototype.cast=function(t,e){return go(t,e,this)},t.prototype.reshape=function(t,e){return yo(t,e)},t.prototype.avgPool=function(t,e){return this.assertNotComplex(t,"avgPool"),this.pool(t,e,"avg").toFloat()},t.prototype.resizeBilinear=function(t,e,n,r){this.assertNotComplex(t,"resizeBilinear");for(var o=t.shape,a=o[0],i=o[1],s=o[2],u=o[3],l=this.readSync(t.dataId),c=new Float32Array(v([a,e,n,u])),h=[r&&e>1?i-1:i,r&&n>1?s-1:s],p=[r&&e>1?e-1:e,r&&n>1?n-1:n],f=0,d=h[0]/p[0],m=h[1]/p[1],g=0;g1?a-1:a,n&&c>1?i-1:i],f=[n&&l>1?l-1:l,n&&c>1?c-1:c],d=p[0]/f[0],v=p[1]/f[1],m=this.readSync(t.dataId),g=0,y=0;y1?i-1:i,r&&n>1?s-1:s],p=[r&&e>1?e-1:e,r&&n>1?n-1:n],f=h[0]/p[0],d=h[1]/p[1],v=0,m=0;m1?a-1:a,n&&c>1?i-1:i],d=[n&&l>1?l-1:l,n&&c>1?c-1:c],v=f[0]/d[0],m=f[1]/d[1],g=1/v,y=1/m,x=2*Math.ceil(g)+2,b=2*Math.ceil(y)+2,w=0;w=l)){var M=C+F*t.strides[1],B=F*v;if(E===Math.min(a-1,n?Math.round(B):Math.floor(B)))for(var P=0;P=c)){var W=M+L*t.strides[2],U=L*m;N===Math.min(i-1,n?Math.round(U):Math.floor(U))&&(_+=p[W+D])}}}}h[S+D]=_}return kn(h,e.shape,e.dtype)},t.prototype.batchNormalization=function(t,e,n,r,o,a){this.assertNotComplex([t,e,n,o,a],"batchNorm");for(var i=this.readSync(t.dataId),s=this.readSync(e.dataId),u=this.readSync(n.dataId),l=o?this.readSync(o.dataId):new Float32Array([1]),c=a?this.readSync(a.dataId):new Float32Array([0]),h=new Float32Array(i.length),p=c.length,f=l.length,d=u.length,v=s.length,m=0,g=0,y=0,x=0,b=0;b=p&&(m=0),g>=v&&(g=0),y>=f&&(y=0),x>=d&&(x=0);return kn(h,t.shape)},t.prototype.localResponseNormalization4D=function(t,e,n,r,o){this.assertNotComplex(t,"localResponseNormalization4D");var a=t.shape[3],i=a-1,s=this.readSync(t.dataId),u=t.size,l=new Float32Array(u);function c(t){for(var n=t%a,r=t-n+Math.max(0,n-e),o=t-n+Math.min(n+e,i),u=0;r<=o;r++){var l=s[r];u+=l*l}return u}for(var h=0;h=0&&a[i]1,function(){return"blockSize should be > 1 for depthToSpace, but was: "+e});for(var r=t.shape[0],o=t.shape[1],a=t.shape[2],i=t.shape[3],s=o*e,u=a*e,l=i/(e*e),c=this.readSync(t.dataId),p=new Float32Array(r*s*u*l),f=0,d=0;d=s))for(var N=p>1?(R-C)*(u-1)/(p-1):0,S=f>1?(I-E)*(l-1)/(f-1):0,A=0;A1?C*(u-1)+A*N:.5*(C+R)*(u-1);if(T<0||T>u-1)for(var D=0;D1?E*(l-1)+D*S:.5*(E+I)*(l-1))<0||q>l-1)for(_=0;_1?E*(l-1)+D*S:.5*(E+I)*(l-1))<0||q>l-1)for(_=0;_=t.size/s)throw new Error("Invalid indices: "+f+" does not index into "+t.shape);for(var g=0;g=r/o)throw new Error("Invalid indices: "+v+" does not index into "+n);for(var x=0;x0,function(){return"scheme must not be an empty string."});var r=t.getInstance();h(null==r.managers[e],function(){return"A model store manager is already registered for scheme '"+e+"'."}),r.managers[e]=n},t.getManager=function(t){var e=this.getInstance().managers[t];if(null==e)throw new Error("Cannot find model manager for scheme '"+t+"'");return e},t.getSchemes=function(){return Object.keys(this.getInstance().managers)},t}();function Ah(t){if(-1===t.indexOf(Nh))throw new Error("The url string provided does not contain a scheme. Supported schemes are: "+Sh.getSchemes().join(","));return{scheme:t.split(Nh)[0],path:t.split(Nh)[1]}}function Th(t,e,o){return void 0===o&&(o=!1),n(this,void 0,void 0,function(){var n,a,i,s,u,l,c,p,f;return r(this,function(r){switch(r.label){case 0:return h(t!==e,function(){return"Old path and new path are the same: '"+t+"'"}),h((n=kh.getLoadHandlers(t)).length>0,function(){return"Copying failed because no load handler is found for source URL "+t+"."}),h(n.length<2,function(){return"Copying failed because more than one ("+n.length+") load handlers for source URL "+t+"."}),a=n[0],h((i=kh.getSaveHandlers(e)).length>0,function(){return"Copying failed because no save handler is found for destination URL "+e+"."}),h(i.length<2,function(){return"Copying failed because more than one ("+n.length+") save handlers for destination URL "+e+"."}),s=i[0],u=Ah(t).scheme,l=Ah(t).path,c=u===Ah(t).scheme,[4,a.load()];case 1:return p=r.sent(),o&&c?[4,Sh.getManager(u).removeModel(l)]:[3,3];case 2:r.sent(),r.label=3;case 3:return[4,s.save(p)];case 4:return f=r.sent(),!o||c?[3,6]:[4,Sh.getManager(u).removeModel(l)];case 5:r.sent(),r.label=6;case 6:return[2,f.modelArtifactsInfo]}})})}var Dh="models_store",_h="model_info_store";function Oh(){if(!a().getBool("IS_BROWSER"))throw new Error("Failed to obtain IndexedDB factory because the current environmentis not a web browser.");var t=window,e=t.indexedDB||t.mozIndexedDB||t.webkitIndexedDB||t.msIndexedDB||t.shimIndexedDB;if(null==e)throw new Error("The current browser does not appear to support IndexedDB.");return e}function Fh(t){var e=t.result;e.createObjectStore(Dh,{keyPath:"modelPath"}),e.createObjectStore(_h,{keyPath:"modelPath"})}var Mh=function(){function t(t){if(this.indexedDB=Oh(),null==t||!t)throw new Error("For IndexedDB, modelPath must not be null, undefined or empty.");this.modelPath=t}return t.prototype.save=function(t){return n(this,void 0,void 0,function(){return r(this,function(e){if(t.modelTopology instanceof ArrayBuffer)throw new Error("BrowserLocalStorage.save() does not support saving model topology in binary formats yet.");return[2,this.databaseAction(this.modelPath,t)]})})},t.prototype.load=function(){return n(this,void 0,void 0,function(){return r(this,function(t){return[2,this.databaseAction(this.modelPath)]})})},t.prototype.databaseAction=function(t,e){var n=this;return new Promise(function(t,r){var o=n.indexedDB.open("tensorflowjs",1);o.onupgradeneeded=function(){return Fh(o)},o.onsuccess=function(){var a=o.result;if(null==e){var i=a.transaction(Dh,"readonly"),s=i.objectStore(Dh).get(n.modelPath);s.onsuccess=function(){if(null==s.result)return a.close(),r(new Error("Cannot find model with path '"+n.modelPath+"' in IndexedDB."));t(s.result.modelArtifacts)},s.onerror=function(t){return a.close(),r(s.error)},i.oncomplete=function(){return a.close()}}else{var u,l=Ih(e),c=a.transaction(_h,"readwrite"),h=c.objectStore(_h),p=h.put({modelPath:n.modelPath,modelArtifactsInfo:l});p.onsuccess=function(){var o=(u=a.transaction(Dh,"readwrite")).objectStore(Dh).put({modelPath:n.modelPath,modelArtifacts:e,modelArtifactsInfo:l});o.onsuccess=function(){return t({modelArtifactsInfo:l})},o.onerror=function(t){var e=(h=c.objectStore(_h)).delete(n.modelPath);e.onsuccess=function(){return a.close(),r(o.error)},e.onerror=function(t){return a.close(),r(o.error)}}},p.onerror=function(t){return a.close(),r(p.error)},c.oncomplete=function(){null==u?a.close():u.oncomplete=function(){return a.close()}}}},o.onerror=function(t){return r(o.error)}})},t.URL_SCHEME="indexeddb://",t}(),Bh=function(t){return a().getBool("IS_BROWSER")&&!Array.isArray(t)&&t.startsWith(Mh.URL_SCHEME)?(e=t.slice(Mh.URL_SCHEME.length),new Mh(e)):null;var e};kh.registerSaveRouter(Bh),kh.registerLoadRouter(Bh);var Ph=function(){function t(){this.indexedDB=Oh()}return t.prototype.listModels=function(){return n(this,void 0,void 0,function(){var t=this;return r(this,function(e){return[2,new Promise(function(e,n){var r=t.indexedDB.open("tensorflowjs",1);r.onupgradeneeded=function(){return Fh(r)},r.onsuccess=function(){var t=r.result,o=t.transaction(_h,"readonly"),a=o.objectStore(_h).getAll();a.onsuccess=function(){for(var t={},n=0,r=a.result;n0,function(){return"promises must be a none empty array"})}(t),function(t,e){h(t>=0&&t<=1,function(){return"Progress fraction must be in range [0, 1], but got startFraction "+t}),h(e>=0&&e<=1,function(){return"Progress fraction must be in range [0, 1], but got endFraction "+e}),h(e>=t,function(){return"startFraction must be no more than endFraction, but got startFraction "+t+" and endFraction "+e})}(n=null==n?0:n,r=null==r?1:r);var o=0;return Promise.all(t.map(function(a){return a.then(function(a){var i=n+ ++o/t.length*(r-n);return e(i),a}),a}))}function rp(t,e){return n(this,void 0,void 0,function(){var n,o,i,s,u,l,c,h,p;return r(this,function(r){switch(r.label){case 0:return null==e&&(e={}),n=null==e.fetchFunc?a().platform.fetch:e.fetchFunc,o=t.map(function(t){return n(t,e.requestInit,{isBinary:!0})}),i=0,s=.5,null!=e.onProgress?[3,2]:[4,Promise.all(o)];case 1:return u=r.sent(),[3,4];case 2:return[4,np(o,e.onProgress,i,s)];case 3:u=r.sent(),r.label=4;case 4:return l=u.map(function(t){return t.arrayBuffer()}),c=.5,h=1,null!=e.onProgress?[3,6]:[4,Promise.all(l)];case 5:return p=r.sent(),[3,8];case 6:return[4,np(l,e.onProgress,c,h)];case 7:p=r.sent(),r.label=8;case 8:return[2,p]}})})}function op(t){var e=this;return function(o,a,i){return void 0===a&&(a=""),n(e,void 0,void 0,function(){var e,n,s,u,l,c,h,p,f,d;return r(this,function(r){switch(r.label){case 0:if(e=o.map(function(){return!1}),n={},s=null!=i?i.map(function(){return!1}):[],u=[],o.forEach(function(t,r){var o=0;t.weights.forEach(function(t){var a="quantization"in t?t.quantization.dtype:t.dtype,l=gh[a]*v(t.shape),c=function(){e[r]=!0,null==n[r]&&(n[r]=[]),n[r].push({manifestEntry:t,groupOffset:o,sizeBytes:l})};null!=i?i.forEach(function(e,n){e===t.name&&(c(),s[n]=!0)}):c(),u.push(t.name),o+=l})}),!s.every(function(t){return t}))throw l=i.filter(function(t,e){return!s[e]}),new Error("Could not find weights in manifest with names: "+l.join(", ")+". \nManifest JSON has weights with names: "+u.join(", ")+".");return c=e.reduce(function(t,e,n){return e&&t.push(n),t},[]),h=[],c.forEach(function(t){o[t].paths.forEach(function(t){var e=a+(a.endsWith("/")?"":"/")+t;h.push(e)})}),[4,t(h)];case 1:return p=r.sent(),f={},d=0,c.forEach(function(t){for(var e=o[t].paths.length,r=0,a=0;a0,function(){return"URL path for http must not be null, undefined or empty."}),Array.isArray(t)&&h(2===t.length,function(){return"URL paths for http must have a length of 2, (actual length is "+t.length+")."}),this.path=t,null!=e.requestInit&&null!=e.requestInit.body)throw new Error("requestInit is expected to have no pre-existing body, but has one.");this.requestInit=e.requestInit||{}}return t.prototype.save=function(t){return n(this,void 0,void 0,function(){var e,n,o,a;return r(this,function(r){switch(r.label){case 0:if(t.modelTopology instanceof ArrayBuffer)throw new Error("BrowserHTTPRequest.save() does not support saving model topology in binary formats yet.");return(e=Object.assign({method:this.DEFAULT_METHOD},this.requestInit)).body=new FormData,n=[{paths:["./model.weights.bin"],weights:t.weightSpecs}],o={modelTopology:t.modelTopology,format:t.format,generatedBy:t.generatedBy,convertedBy:t.convertedBy,userDefinedMetadata:t.userDefinedMetadata,weightsManifest:n},e.body.append("model.json",new Blob([JSON.stringify(o)],{type:"application/json"}),"model.json"),null!=t.weightData&&e.body.append("model.weights.bin",new Blob([t.weightData],{type:"application/octet-stream"}),"model.weights.bin"),[4,this.fetch(this.path,e)];case 1:if((a=r.sent()).ok)return[2,{modelArtifactsInfo:Ih(t),responses:[a]}];throw new Error("BrowserHTTPRequest.save() failed due to HTTP response status "+a.status+".")}})})},t.prototype.load=function(){return n(this,void 0,void 0,function(){var t,e,n,o,a,i,s,u;return r(this,function(r){switch(r.label){case 0:return[4,this.fetch(this.path,this.requestInit)];case 1:if(!(t=r.sent()).ok)throw new Error("Request to "+this.path+" failed with status code "+t.status+". Please verify this URL points to the model JSON of the model to load.");r.label=2;case 2:return r.trys.push([2,4,,5]),[4,t.json()];case 3:return e=r.sent(),[3,5];case 4:throw r.sent(),n="Failed to parse model JSON of response from "+this.path+".",this.path.endsWith(".pb")?n+=" Your path contains a .pb file extension. Support for .pb models have been removed in TensorFlow.js 1.0 in favor of .json models. You can re-convert your Python TensorFlow model using the TensorFlow.js 1.0 conversion scripts or you can convert your.pb models with the 'pb2json'NPM script in the tensorflow/tfjs-converter repository.":n+=" Please make sure the server is serving valid JSON for this request.",new Error(n);case 5:if(o=e.modelTopology,a=e.weightsManifest,null==o&&null==a)throw new Error("The JSON from HTTP path "+this.path+" contains neither model topology or manifest for weights.");return null==a?[3,7]:[4,this.loadWeights(a)];case 6:u=r.sent(),i=u[0],s=u[1],r.label=7;case 7:return[2,{modelTopology:o,weightSpecs:i,weightData:s}]}})})},t.prototype.loadWeights=function(t){return n(this,void 0,void 0,function(){var e,n,o,a,i,s,u,l,c,h,p;return r(this,function(r){switch(r.label){case 0:for(e=Array.isArray(this.path)?this.path[1]:this.path,n=function(t){var e=t.lastIndexOf("/"),n=t.lastIndexOf("?"),r=t.substring(0,e),o=n>e?t.substring(n):"";return[r+"/",o]}(e),o=n[0],a=n[1],i=this.weightPathPrefix||o,s=[],u=0,l=t;u0&&Number.isInteger(n),function(){return"If provided, numClasses must be a positive integer, but got "+n}),h(1===r.rank,function(){return"Expected the rank of labels to be 1, but got "+r.rank}),h(1===o.rank,function(){return"Expected the rank of predictions to be 1, but got "+o.rank}),h(r.shape[0]===o.shape[0],function(){return"Mismatch in the number of examples: "+r.shape[0]+" vs. "+o.shape[0]+". Labels and predictions should have the same number of elements."}),h(n>0&&Number.isInteger(n),function(){return"numClasses is required to be a positive integer, but got "+n});var a=cr(r.asType("int32"),n),i=cr(o.asType("int32"),n);return a.transpose().matMul(i).asType("int32")}}),fp=Object.freeze({confusionMatrix:pp});var dp=mn({fromPixels_:function(t,e){if(void 0===e&&(e=3),e>4)throw new Error("Cannot construct Tensor with more than 4 channels from pixels.");var n="undefined"!=typeof HTMLVideoElement&&t instanceof HTMLVideoElement;if(n&&n&&t.readyState<2)throw new Error("The video element has not loaded data yet. Please wait for `loadeddata` event on the