From 0310afb30a4e15b0615b131efd9826bd1b9fb294 Mon Sep 17 00:00:00 2001 From: Trieu Date: Thu, 15 Aug 2019 16:11:45 +0700 Subject: [PATCH] Created using Colaboratory --- ...amese_Backtranslation_Model_Analysis.ipynb | 879 +----------------- 1 file changed, 30 insertions(+), 849 deletions(-) diff --git a/colab/Vietnamese_Backtranslation_Model_Analysis.ipynb b/colab/Vietnamese_Backtranslation_Model_Analysis.ipynb index b9b470c..90ea975 100644 --- a/colab/Vietnamese_Backtranslation_Model_Analysis.ipynb +++ b/colab/Vietnamese_Backtranslation_Model_Analysis.ipynb @@ -23,7 +23,7 @@ "colab_type": "text" }, "source": [ - "\"Open" + "\"Open" ] }, { @@ -73,11 +73,7 @@ "metadata": { "id": "kRO6TXGLT4Qb", "colab_type": "code", - "outputId": "7b0fa9e5-dd35-4c8b-b29c-d6da8a634622", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 384 - } + "colab": {} }, "source": [ "print('\\nInstalling gcsfuse')\n", @@ -87,34 +83,7 @@ "!apt -qq install gcsfuse" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "\n", - "Installing gcsfuse\n", - " % Total % Received % Xferd Average Speed Time Time Time Current\n", - " Dload Upload Total Spent Left Speed\n", - "100 659 100 659 0 0 21258 0 --:--:-- --:--:-- --:--:-- 21966\n", - "OK\n", - "25 packages can be upgraded. Run 'apt list --upgradable' to see them.\n", - "The following package was automatically installed and is no longer required:\n", - " libnvidia-common-410\n", - "Use 'apt autoremove' to remove it.\n", - "The following NEW packages will be installed:\n", - " gcsfuse\n", - "0 upgraded, 1 newly installed, 0 to remove and 25 not upgraded.\n", - "Need to get 4,274 kB of archives.\n", - "After this operation, 12.8 MB of additional disk space will be used.\n", - "Selecting previously unselected package gcsfuse.\n", - "(Reading database ... 131289 files and directories currently installed.)\n", - "Preparing to unpack .../gcsfuse_0.28.1_amd64.deb ...\n", - "Unpacking gcsfuse (0.28.1) ...\n", - "Setting up gcsfuse (0.28.1) ...\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -131,11 +100,7 @@ "metadata": { "id": "HuA_J2nnUHWp", "colab_type": "code", - "outputId": "bd384762-a0df-4deb-c1e3-cf3b12ba78d8", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 193 - } + "colab": {} }, "source": [ "from google.colab import auth\n", @@ -159,34 +124,14 @@ "auth.authenticate_user()" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "WARNING: Logging before flag parsing goes to stderr.\n", - "W0803 08:48:21.182517 140300811634560 lazy_loader.py:50] \n", - "The TensorFlow contrib module will not be included in TensorFlow 2.0.\n", - "For more information, please see:\n", - " * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n", - " * https://github.com/tensorflow/addons\n", - " * https://github.com/tensorflow/io (for I/O related ops)\n", - "If you depend on functionality not listed there, please file an issue.\n", - "\n" - ], - "name": "stderr" - } - ] + "outputs": [] }, { "cell_type": "code", "metadata": { "id": "9priC3hHUVaX", "colab_type": "code", - "outputId": "d9446456-f76c-435e-eddc-ffead6f82dc2", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 176 - } + "colab": {} }, "source": [ "# Now we mount the local storage to the google cloud bucket.\n", @@ -202,22 +147,7 @@ "!ls $mount_point" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Mounting bucket vien-translation to local.\n", - "fusermount: failed to unmount /content/vien-translation: Invalid argument\n", - "Using mount point: /content/vien-translation\n", - "Opening GCS connection...\n", - "Opening bucket...\n", - "Mounting file system...\n", - "File system has been successfully mounted.\n", - "checkpoints data foody_sa raw tmp\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -238,9 +168,9 @@ "colab_type": "text" }, "source": [ - "### From our VietAI's github **vietai/back_translate**\n", + "### From our VietAI's github `vietai/dab`\n", "\n", - "We clone from vietai/back_translate for declaring ViEn problem" + "We clone from `vietai/dab` for declaring ViEn problem" ] }, { @@ -248,40 +178,20 @@ "metadata": { "id": "y4ceNVTXipHN", "colab_type": "code", - "outputId": "75ff147e-23c5-49a8-e90a-84fab39cee81", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 173 - } + "colab": {} }, "source": [ - "src = '/content/back_translate'\n", + "src = '/content/dab'\n", "if not os.path.exists(src):\n", - " !git clone https://github.com/vietai/back_translate.git\n", - " %cd \"back_translate\"\n", + " !git clone https://github.com/vietai/dab.git\n", + " %cd $src\n", "else:\n", - " %cd \"back_translate\"\n", + " %cd $src\n", " !git pull\n", "!ls" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Cloning into 'back_translate'...\n", - "remote: Enumerating objects: 76, done.\u001b[K\n", - "remote: Counting objects: 100% (76/76), done.\u001b[K\n", - "remote: Compressing objects: 100% (50/50), done.\u001b[K\n", - "remote: Total 76 (delta 43), reused 53 (delta 23), pack-reused 0\u001b[K\n", - "Unpacking objects: 100% (76/76), done.\n", - "/content/back_translate\n", - "back_translate.py LICENSE\tREADME.md\tt2t_decoder.py\n", - "decoding.py\t problems.py\tt2t_datagen.py\tt2t_trainer.py\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -291,7 +201,7 @@ }, "source": [ "### From Tensor2Tensor\n", - "We then build Tensor2Tensor from source and import it for later usage. Because the tensor2tensor library provide EnVi problem only, we need to run **back_translate/problems.py** to register ViEn problem (for translating from Vietnamese in English) to tensor2tensor registry." + "We then build Tensor2Tensor from source and import it for later usage. Because the tensor2tensor library provide EnVi problem only, we need to run **dab/problems.py** to register ViEn problem (for translating from Vietnamese in English) to tensor2tensor registry." ] }, { @@ -299,11 +209,7 @@ "metadata": { "id": "ZgMe553hvYLK", "colab_type": "code", - "outputId": "61bd51ce-d090-4006-d66d-68e999f3f26c", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - } + "colab": {} }, "source": [ "if not os.path.exists(\"tensor2tensor\"):\n", @@ -328,173 +234,7 @@ "%cd .." ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Cloning into 'tensor2tensor'...\n", - "remote: Enumerating objects: 28133, done.\u001b[K\n", - "remote: Total 28133 (delta 0), reused 0 (delta 0), pack-reused 28133\u001b[K\n", - "Receiving objects: 100% (28133/28133), 13.27 MiB | 5.07 MiB/s, done.\n", - "Resolving deltas: 100% (22712/22712), done.\n", - "/content/back_translate/tensor2tensor\n", - "Processing /content/back_translate/tensor2tensor\n", - "Requirement already satisfied: bz2file in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.98)\n", - "Requirement already satisfied: dopamine-rl in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.0.5)\n", - "Requirement already satisfied: flask in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.1.1)\n", - "Requirement already satisfied: future in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.16.0)\n", - "Requirement already satisfied: gevent in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.4.0)\n", - "Requirement already satisfied: gin-config in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.2.0)\n", - "Requirement already satisfied: google-api-python-client in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.7.9)\n", - "Requirement already satisfied: gunicorn in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (19.9.0)\n", - "Requirement already satisfied: gym in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.10.11)\n", - "Requirement already satisfied: h5py in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (2.8.0)\n", - "Collecting kfac (from tensor2tensor==1.13.4)\n", - "\u001b[?25l Downloading https://files.pythonhosted.org/packages/83/6f/937896d2d4156db31bca44f9137badee33783bf5a7744436b1cf5a75d157/kfac-0.1.4-py2.py3-none-any.whl (140kB)\n", - "\u001b[K |████████████████████████████████| 143kB 40.5MB/s \n", - "\u001b[?25hRequirement already satisfied: mesh-tensorflow in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.0.5)\n", - "Requirement already satisfied: numpy in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.16.4)\n", - "Requirement already satisfied: oauth2client in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (4.1.3)\n", - "Requirement already satisfied: opencv-python in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (3.4.5.20)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (4.3.0)\n", - "Collecting pypng (from tensor2tensor==1.13.4)\n", - "\u001b[?25l Downloading https://files.pythonhosted.org/packages/bc/fb/f719f1ac965e2101aa6ea6f54ef8b40f8fbb033f6ad07c017663467f5147/pypng-0.0.20.tar.gz (649kB)\n", - "\u001b[K |████████████████████████████████| 655kB 47.9MB/s \n", - "\u001b[?25hRequirement already satisfied: requests in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (2.21.0)\n", - "Requirement already satisfied: scipy in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.2.2)\n", - "Requirement already satisfied: six in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.12.0)\n", - "Requirement already satisfied: sympy in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (1.1.1)\n", - "Collecting tensorflow-datasets (from tensor2tensor==1.13.4)\n", - "\u001b[?25l Downloading https://files.pythonhosted.org/packages/63/32/602a49ef794624c2fbc47695a0d3135141ba330f6eb14091f12f28baf6d6/tensorflow_datasets-1.1.0-py2-none-any.whl (933kB)\n", - "\u001b[K |████████████████████████████████| 942kB 51.3MB/s \n", - "\u001b[?25hRequirement already satisfied: tensorflow-probability in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (0.7.0)\n", - "Requirement already satisfied: tqdm in /usr/local/lib/python2.7/dist-packages (from tensor2tensor==1.13.4) (4.28.1)\n", - "Requirement already satisfied: absl-py>=0.2.2 in /usr/local/lib/python2.7/dist-packages (from dopamine-rl->tensor2tensor==1.13.4) (0.7.1)\n", - "Requirement already satisfied: click>=5.1 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor==1.13.4) (7.0)\n", - "Requirement already satisfied: Werkzeug>=0.15 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor==1.13.4) (0.15.5)\n", - "Requirement already satisfied: itsdangerous>=0.24 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor==1.13.4) (1.1.0)\n", - "Requirement already satisfied: Jinja2>=2.10.1 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor==1.13.4) (2.10.1)\n", - "Requirement already satisfied: greenlet>=0.4.14; platform_python_implementation == \"CPython\" in /usr/local/lib/python2.7/dist-packages (from gevent->tensor2tensor==1.13.4) (0.4.15)\n", - "Requirement already satisfied: enum34; python_version < \"3\" in /usr/local/lib/python2.7/dist-packages (from gin-config->tensor2tensor==1.13.4) (1.1.6)\n", - "Requirement already satisfied: google-auth-httplib2>=0.0.3 in /usr/local/lib/python2.7/dist-packages (from google-api-python-client->tensor2tensor==1.13.4) (0.0.3)\n", - "Requirement already satisfied: google-auth>=1.4.1 in /usr/local/lib/python2.7/dist-packages (from google-api-python-client->tensor2tensor==1.13.4) (1.4.2)\n", - "Requirement already satisfied: httplib2<1dev,>=0.9.2 in /usr/local/lib/python2.7/dist-packages (from google-api-python-client->tensor2tensor==1.13.4) (0.11.3)\n", - "Requirement already satisfied: uritemplate<4dev,>=3.0.0 in /usr/local/lib/python2.7/dist-packages (from google-api-python-client->tensor2tensor==1.13.4) (3.0.0)\n", - "Requirement already satisfied: pyglet>=1.2.0 in /usr/local/lib/python2.7/dist-packages (from gym->tensor2tensor==1.13.4) (1.4.1)\n", - "Requirement already satisfied: rsa>=3.1.4 in /usr/local/lib/python2.7/dist-packages (from oauth2client->tensor2tensor==1.13.4) (4.0)\n", - "Requirement already satisfied: pyasn1>=0.1.7 in /usr/local/lib/python2.7/dist-packages (from oauth2client->tensor2tensor==1.13.4) (0.4.5)\n", - "Requirement already satisfied: pyasn1-modules>=0.0.5 in /usr/local/lib/python2.7/dist-packages (from oauth2client->tensor2tensor==1.13.4) (0.2.5)\n", - "Requirement already satisfied: olefile in /usr/local/lib/python2.7/dist-packages (from Pillow->tensor2tensor==1.13.4) (0.46)\n", - "Requirement already satisfied: urllib3<1.25,>=1.21.1 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor==1.13.4) (1.24.3)\n", - "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor==1.13.4) (2019.6.16)\n", - "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor==1.13.4) (3.0.4)\n", - "Requirement already satisfied: idna<2.9,>=2.5 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor==1.13.4) (2.8)\n", - "Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python2.7/dist-packages (from sympy->tensor2tensor==1.13.4) (1.1.0)\n", - "Requirement already satisfied: futures in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (3.2.0)\n", - "Requirement already satisfied: wrapt in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (1.11.2)\n", - "Requirement already satisfied: promise in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (2.2.1)\n", - "Requirement already satisfied: dill in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (0.3.0)\n", - "Requirement already satisfied: tensorflow-metadata in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (0.14.0)\n", - "Requirement already satisfied: termcolor in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (1.1.0)\n", - "Requirement already satisfied: functools32 in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (3.2.3.post2)\n", - "Requirement already satisfied: attrs in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (19.1.0)\n", - "Requirement already satisfied: protobuf>=3.6.1 in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (3.7.1)\n", - "Requirement already satisfied: psutil in /usr/local/lib/python2.7/dist-packages (from tensorflow-datasets->tensor2tensor==1.13.4) (5.4.8)\n", - "Requirement already satisfied: cloudpickle>=0.6.1 in /usr/local/lib/python2.7/dist-packages (from tensorflow-probability->tensor2tensor==1.13.4) (0.6.1)\n", - "Requirement already satisfied: decorator in /usr/local/lib/python2.7/dist-packages (from tensorflow-probability->tensor2tensor==1.13.4) (4.4.0)\n", - "Requirement already satisfied: MarkupSafe>=0.23 in /usr/local/lib/python2.7/dist-packages (from Jinja2>=2.10.1->flask->tensor2tensor==1.13.4) (1.1.1)\n", - "Requirement already satisfied: cachetools>=2.0.0 in /usr/local/lib/python2.7/dist-packages (from google-auth>=1.4.1->google-api-python-client->tensor2tensor==1.13.4) (3.1.1)\n", - "Requirement already satisfied: typing>=3.6.4; python_version < \"3.5\" in /usr/local/lib/python2.7/dist-packages (from promise->tensorflow-datasets->tensor2tensor==1.13.4) (3.7.4)\n", - "Requirement already satisfied: googleapis-common-protos in /usr/local/lib/python2.7/dist-packages (from tensorflow-metadata->tensorflow-datasets->tensor2tensor==1.13.4) (1.6.0)\n", - "Requirement already satisfied: setuptools in /usr/local/lib/python2.7/dist-packages (from protobuf>=3.6.1->tensorflow-datasets->tensor2tensor==1.13.4) (41.0.1)\n", - "Building wheels for collected packages: tensor2tensor, pypng\n", - " Building wheel for tensor2tensor (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for tensor2tensor: filename=tensor2tensor-1.13.4-cp27-none-any.whl size=1539821 sha256=67c6094042a882f0c44b98f6fe1de74e06f5b046291f8e094ef1d4d9f6640f16\n", - " Stored in directory: /tmp/pip-ephem-wheel-cache-SN03KR/wheels/9b/66/4b/c8d911abdc4eac28bab71c8ebbcf828ad59ab2cf1ad4aa5e12\n", - " Building wheel for pypng (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for pypng: filename=pypng-0.0.20-cp27-none-any.whl size=67162 sha256=a89bccaf629dd7d9249aaff1a41a9265d27cf0730dc7c280c51711410d4718f7\n", - " Stored in directory: /root/.cache/pip/wheels/41/6b/ef/0493b536b6d4722c2ae9486691b1d49b922b9877922beeabb3\n", - "Successfully built tensor2tensor pypng\n", - "Installing collected packages: kfac, pypng, tensorflow-datasets, tensor2tensor\n", - " Found existing installation: tensor2tensor 1.11.0\n", - " Uninstalling tensor2tensor-1.11.0:\n", - " Successfully uninstalled tensor2tensor-1.11.0\n", - "Successfully installed kfac-0.1.4 pypng-0.0.20 tensor2tensor-1.13.4 tensorflow-datasets-1.1.0\n" - ], - "name": "stdout" - }, - { - "output_type": "stream", - "text": [ - "W0803 08:49:45.299123 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/expert_utils.py:68: The name tf.variable_scope is deprecated. Please use tf.compat.v1.variable_scope instead.\n", - "\n", - "W0803 08:49:47.754268 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/adafactor.py:27: The name tf.train.Optimizer is deprecated. Please use tf.compat.v1.train.Optimizer instead.\n", - "\n", - "W0803 08:49:47.756233 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/multistep_optimizer.py:32: The name tf.train.AdamOptimizer is deprecated. Please use tf.compat.v1.train.AdamOptimizer instead.\n", - "\n", - "W0803 08:49:47.814990 140300811634560 deprecation_wrapper.py:119] From /usr/local/lib/python2.7/dist-packages/mesh_tensorflow/ops.py:4237: The name tf.train.CheckpointSaverListener is deprecated. Please use tf.estimator.CheckpointSaverListener instead.\n", - "\n", - "W0803 08:49:47.815905 140300811634560 deprecation_wrapper.py:119] From /usr/local/lib/python2.7/dist-packages/mesh_tensorflow/ops.py:4260: The name tf.train.SessionRunHook is deprecated. Please use tf.estimator.SessionRunHook instead.\n", - "\n", - "W0803 08:49:47.904783 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/models/research/neural_stack.py:38: The name tf.nn.rnn_cell.RNNCell is deprecated. Please use tf.compat.v1.nn.rnn_cell.RNNCell instead.\n", - "\n", - "W0803 08:49:48.320621 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/rl/gym_utils.py:235: The name tf.logging.info is deprecated. Please use tf.compat.v1.logging.info instead.\n", - "\n", - "W0803 08:49:48.386665 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/trainer_lib.py:111: The name tf.OptimizerOptions is deprecated. Please use tf.compat.v1.OptimizerOptions instead.\n", - "\n" - ], - "name": "stderr" - }, - { - "output_type": "stream", - "text": [ - "/content/back_translate\n" - ], - "name": "stdout" - }, - { - "output_type": "stream", - "text": [ - "tensor2tensor/data_generators/video_generated.py:34: UserWarning: \n", - "This call to matplotlib.use() has no effect because the backend has already\n", - "been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,\n", - "or matplotlib.backends is imported for the first time.\n", - "\n", - "The backend was *originally* set to 'module://ipykernel.pylab.backend_inline' by the following code:\n", - " File \"/usr/lib/python2.7/runpy.py\", line 174, in _run_module_as_main\n", - " \"__main__\", fname, loader, pkg_name)\n", - " File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n", - " exec code in run_globals\n", - " File \"/usr/local/lib/python2.7/dist-packages/ipykernel_launcher.py\", line 16, in \n", - " app.launch_new_instance()\n", - " File \"/usr/local/lib/python2.7/dist-packages/traitlets/config/application.py\", line 657, in launch_instance\n", - " app.initialize(argv)\n", - " File \"\", line 2, in initialize\n", - " File \"/usr/local/lib/python2.7/dist-packages/traitlets/config/application.py\", line 87, in catch_config_error\n", - " return method(app, *args, **kwargs)\n", - " File \"/usr/local/lib/python2.7/dist-packages/ipykernel/kernelapp.py\", line 462, in initialize\n", - " self.init_gui_pylab()\n", - " File \"/usr/local/lib/python2.7/dist-packages/ipykernel/kernelapp.py\", line 403, in init_gui_pylab\n", - " InteractiveShellApp.init_gui_pylab(self)\n", - " File \"/usr/local/lib/python2.7/dist-packages/IPython/core/shellapp.py\", line 213, in init_gui_pylab\n", - " r = enable(key)\n", - " File \"/usr/local/lib/python2.7/dist-packages/IPython/core/interactiveshell.py\", line 2950, in enable_matplotlib\n", - " pt.activate_matplotlib(backend)\n", - " File \"/usr/local/lib/python2.7/dist-packages/IPython/core/pylabtools.py\", line 309, in activate_matplotlib\n", - " matplotlib.pyplot.switch_backend(backend)\n", - " File \"/usr/local/lib/python2.7/dist-packages/matplotlib/pyplot.py\", line 231, in switch_backend\n", - " matplotlib.use(newbackend, warn=False, force=True)\n", - " File \"/usr/local/lib/python2.7/dist-packages/matplotlib/__init__.py\", line 1422, in use\n", - " reload(sys.modules['matplotlib.backends'])\n", - " File \"/usr/local/lib/python2.7/dist-packages/matplotlib/backends/__init__.py\", line 17, in \n", - " line for line in traceback.format_stack()\n", - "\n", - "\n", - " matplotlib.use(\"agg\")\n" - ], - "name": "stderr" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -558,11 +298,7 @@ "metadata": { "id": "-S6AwB_4m3Zq", "colab_type": "code", - "outputId": "aeb3052b-9940-45c1-fc6f-139c0043e2db", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 176 - } + "colab": {} }, "source": [ "vien_problem = problems.problem(\"translate_vien_iwslt32k\")\n", @@ -604,22 +340,7 @@ " return vien_decode(translated_outputs[\"outputs\"]), translated_outputs[\"cache\"]" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "W0803 08:50:05.810746 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/data_generators/text_encoder.py:938: The name tf.gfile.Exists is deprecated. Please use tf.io.gfile.exists instead.\n", - "\n", - "W0803 08:50:06.525468 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/data_generators/text_encoder.py:940: The name tf.gfile.Open is deprecated. Please use tf.io.gfile.GFile instead.\n", - "\n", - "W0803 08:50:08.947407 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/layers/common_layers.py:94: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n", - "\n", - "W0803 08:50:10.205029 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/t2t_model.py:244: The name tf.summary.text is deprecated. Please use tf.compat.v1.summary.text instead.\n", - "\n" - ], - "name": "stderr" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -702,11 +423,7 @@ "id": "XLREuKhVjrxv", "colab_type": "code", "cellView": "both", - "outputId": "dfc541c6-9f8f-4f83-e991-2c17e5b7cd60", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 332 - } + "colab": {} }, "source": [ "beam_size = 4 #@param {type: \"integer\"}\n", @@ -718,37 +435,7 @@ "print(\"The input sentence is tranlated as: \\n{}\".format(en_output_sentence))" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "W0803 08:51:05.001951 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/utils/t2t_model.py:2296: The name tf.get_variable_scope is deprecated. Please use tf.compat.v1.get_variable_scope instead.\n", - "\n", - "W0803 08:51:05.011019 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/layers/modalities.py:475: The name tf.get_variable is deprecated. Please use tf.compat.v1.get_variable instead.\n", - "\n", - "W0803 08:51:05.142455 140300811634560 deprecation.py:323] From tensor2tensor/layers/common_attention.py:857: to_float (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", - "Instructions for updating:\n", - "Use `tf.cast` instead.\n", - "W0803 08:51:05.193547 140300811634560 deprecation.py:323] From tensor2tensor/utils/expert_utils.py:621: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n", - "Instructions for updating:\n", - "Use tf.where in 2.0, which has the same broadcast rule as np.where\n", - "W0803 08:51:05.199455 140300811634560 deprecation.py:323] From tensor2tensor/utils/expert_utils.py:621: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", - "Instructions for updating:\n", - "Use `tf.cast` instead.\n", - "W0803 08:51:05.256160 140300811634560 deprecation_wrapper.py:119] From tensor2tensor/layers/common_layers.py:3077: The name tf.layers.Dense is deprecated. Please use tf.compat.v1.layers.Dense instead.\n", - "\n" - ], - "name": "stderr" - }, - { - "output_type": "stream", - "text": [ - "The input sentence is tranlated as: \n", - "I 'm a good teacher .\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -766,11 +453,7 @@ "id": "GsD9QJjpwxjn", "colab_type": "code", "cellView": "both", - "outputId": "100442c6-97b4-48d6-e79b-00fcaa2dcf60", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 52 - } + "colab": {} }, "source": [ "beam_size = 4 #@param {type: \"integer\"}\n", @@ -782,16 +465,7 @@ "print(\"The input sentence is tranlated as: \\n{}\".format(vi_output_sentence))" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "The input sentence is tranlated as: \n", - "Tôi là một giáo viên tốt .\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -809,11 +483,7 @@ "metadata": { "id": "rgE2fvVjrAj4", "colab_type": "code", - "outputId": "82e8a3ad-ad19-4b33-ff4a-462c5458368c", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 124 - } + "colab": {} }, "source": [ "inputs = \"Tôi là một thầy giáo giỏi\"\n", @@ -823,25 +493,7 @@ "print(\"Outputs: %s\" % outputs.replace(''', '\\''))" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "W0803 08:52:23.519270 140300811634560 deprecation.py:323] From tensor2tensor/models/transformer.py:1221: to_int64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n", - "Instructions for updating:\n", - "Use `tf.cast` instead.\n" - ], - "name": "stderr" - }, - { - "output_type": "stream", - "text": [ - "Inputs: Tôi là một thầy giáo giỏi\n", - "Outputs: I 'm a good teacher .\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "code", @@ -945,25 +597,7 @@ "metadata": { "id": "zu9JDe5zzuh2", "colab_type": "code", - "outputId": "89882f22-9138-44ab-8b0a-cc01416ada65", - "colab": { - "resources": { - "http://localhost:8080/static/components/requirejs/require.js": { - "data": "LyoqIHZpbTogZXQ6dHM9NDpzdz00OnN0cz00CiAqIEBsaWNlbnNlIFJlcXVpcmVKUyAyLjEuMjIgQ29weXJpZ2h0IChjKSAyMDEwLTIwMTUsIFRoZSBEb2pvIEZvdW5kYXRpb24gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogQXZhaWxhYmxlIHZpYSB0aGUgTUlUIG9yIG5ldyBCU0QgbGljZW5zZS4KICogc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL3JlcXVpcmVqcyBmb3IgZGV0YWlscwogKi8KLy9Ob3QgdXNpbmcgc3RyaWN0OiB1bmV2ZW4gc3RyaWN0IHN1cHBvcnQgaW4gYnJvd3NlcnMsICMzOTIsIGFuZCBjYXVzZXMKLy9wcm9ibGVtcyB3aXRoIHJlcXVpcmVqcy5leGVjKCkvdHJhbnNwaWxlciBwbHVnaW5zIHRoYXQgbWF5IG5vdCBiZSBzdHJpY3QuCi8qanNsaW50IHJlZ2V4cDogdHJ1ZSwgbm9tZW46IHRydWUsIHNsb3BweTogdHJ1ZSAqLwovKmdsb2JhbCB3aW5kb3csIG5hdmlnYXRvciwgZG9jdW1lbnQsIGltcG9ydFNjcmlwdHMsIHNldFRpbWVvdXQsIG9wZXJhICovCgp2YXIgcmVxdWlyZWpzLCByZXF1aXJlLCBkZWZpbmU7CihmdW5jdGlvbiAoZ2xvYmFsKSB7CiAgICB2YXIgcmVxLCBzLCBoZWFkLCBiYXNlRWxlbWVudCwgZGF0YU1haW4sIHNyYywKICAgICAgICBpbnRlcmFjdGl2ZVNjcmlwdCwgY3VycmVudGx5QWRkaW5nU2NyaXB0LCBtYWluU2NyaXB0LCBzdWJQYXRoLAogICAgICAgIHZlcnNpb24gPSAnMi4xLjIyJywKICAgICAgICBjb21tZW50UmVnRXhwID0gLyhcL1wqKFtcc1xTXSo/KVwqXC98KFteOl18XilcL1wvKC4qKSQpL21nLAogICAgICAgIGNqc1JlcXVpcmVSZWdFeHAgPSAvW14uXVxzKnJlcXVpcmVccypcKFxzKlsiJ10oW14nIlxzXSspWyInXVxzKlwpL2csCiAgICAgICAganNTdWZmaXhSZWdFeHAgPSAvXC5qcyQvLAogICAgICAgIGN1cnJEaXJSZWdFeHAgPSAvXlwuXC8vLAogICAgICAgIG9wID0gT2JqZWN0LnByb3RvdHlwZSwKICAgICAgICBvc3RyaW5nID0gb3AudG9TdHJpbmcsCiAgICAgICAgaGFzT3duID0gb3AuaGFzT3duUHJvcGVydHksCiAgICAgICAgYXAgPSBBcnJheS5wcm90b3R5cGUsCiAgICAgICAgaXNCcm93c2VyID0gISEodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmRvY3VtZW50KSwKICAgICAgICBpc1dlYldvcmtlciA9ICFpc0Jyb3dzZXIgJiYgdHlwZW9mIGltcG9ydFNjcmlwdHMgIT09ICd1bmRlZmluZWQnLAogICAgICAgIC8vUFMzIGluZGljYXRlcyBsb2FkZWQgYW5kIGNvbXBsZXRlLCBidXQgbmVlZCB0byB3YWl0IGZvciBjb21wbGV0ZQogICAgICAgIC8vc3BlY2lmaWNhbGx5LiBTZXF1ZW5jZSBpcyAnbG9hZGluZycsICdsb2FkZWQnLCBleGVjdXRpb24sCiAgICAgICAgLy8gdGhlbiAnY29tcGxldGUnLiBUaGUgVUEgY2hlY2sgaXMgdW5mb3J0dW5hdGUsIGJ1dCBub3Qgc3VyZSBob3cKICAgICAgICAvL3RvIGZlYXR1cmUgdGVzdCB3L28gY2F1c2luZyBwZXJmIGlzc3Vlcy4KICAgICAgICByZWFkeVJlZ0V4cCA9IGlzQnJvd3NlciAmJiBuYXZpZ2F0b3IucGxhdGZvcm0gPT09ICdQTEFZU1RBVElPTiAzJyA/CiAgICAgICAgICAgICAgICAgICAgICAvXmNvbXBsZXRlJC8gOiAvXihjb21wbGV0ZXxsb2FkZWQpJC8sCiAgICAgICAgZGVmQ29udGV4dE5hbWUgPSAnXycsCiAgICAgICAgLy9PaCB0aGUgdHJhZ2VkeSwgZGV0ZWN0aW5nIG9wZXJhLiBTZWUgdGhlIHVzYWdlIG9mIGlzT3BlcmEgZm9yIHJlYXNvbi4KICAgICAgICBpc09wZXJhID0gdHlwZW9mIG9wZXJhICE9PSAndW5kZWZpbmVkJyAmJiBvcGVyYS50b1N0cmluZygpID09PSAnW29iamVjdCBPcGVyYV0nLAogICAgICAgIGNvbnRleHRzID0ge30sCiAgICAgICAgY2ZnID0ge30sCiAgICAgICAgZ2xvYmFsRGVmUXVldWUgPSBbXSwKICAgICAgICB1c2VJbnRlcmFjdGl2ZSA9IGZhbHNlOwoKICAgIGZ1bmN0aW9uIGlzRnVuY3Rpb24oaXQpIHsKICAgICAgICByZXR1cm4gb3N0cmluZy5jYWxsKGl0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJzsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0FycmF5KGl0KSB7CiAgICAgICAgcmV0dXJuIG9zdHJpbmcuY2FsbChpdCkgPT09ICdbb2JqZWN0IEFycmF5XSc7CiAgICB9CgogICAgLyoqCiAgICAgKiBIZWxwZXIgZnVuY3Rpb24gZm9yIGl0ZXJhdGluZyBvdmVyIGFuIGFycmF5LiBJZiB0aGUgZnVuYyByZXR1cm5zCiAgICAgKiBhIHRydWUgdmFsdWUsIGl0IHdpbGwgYnJlYWsgb3V0IG9mIHRoZSBsb29wLgogICAgICovCiAgICBmdW5jdGlvbiBlYWNoKGFyeSwgZnVuYykgewogICAgICAgIGlmIChhcnkpIHsKICAgICAgICAgICAgdmFyIGk7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnkubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgICAgICAgIGlmIChhcnlbaV0gJiYgZnVuYyhhcnlbaV0sIGksIGFyeSkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKioKICAgICAqIEhlbHBlciBmdW5jdGlvbiBmb3IgaXRlcmF0aW5nIG92ZXIgYW4gYXJyYXkgYmFja3dhcmRzLiBJZiB0aGUgZnVuYwogICAgICogcmV0dXJucyBhIHRydWUgdmFsdWUsIGl0IHdpbGwgYnJlYWsgb3V0IG9mIHRoZSBsb29wLgogICAgICovCiAgICBmdW5jdGlvbiBlYWNoUmV2ZXJzZShhcnksIGZ1bmMpIHsKICAgICAgICBpZiAoYXJ5KSB7CiAgICAgICAgICAgIHZhciBpOwogICAgICAgICAgICBmb3IgKGkgPSBhcnkubGVuZ3RoIC0gMTsgaSA+IC0xOyBpIC09IDEpIHsKICAgICAgICAgICAgICAgIGlmIChhcnlbaV0gJiYgZnVuYyhhcnlbaV0sIGksIGFyeSkpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBmdW5jdGlvbiBoYXNQcm9wKG9iaiwgcHJvcCkgewogICAgICAgIHJldHVybiBoYXNPd24uY2FsbChvYmosIHByb3ApOwogICAgfQoKICAgIGZ1bmN0aW9uIGdldE93bihvYmosIHByb3ApIHsKICAgICAgICByZXR1cm4gaGFzUHJvcChvYmosIHByb3ApICYmIG9ialtwcm9wXTsKICAgIH0KCiAgICAvKioKICAgICAqIEN5Y2xlcyBvdmVyIHByb3BlcnRpZXMgaW4gYW4gb2JqZWN0IGFuZCBjYWxscyBhIGZ1bmN0aW9uIGZvciBlYWNoCiAgICAgKiBwcm9wZXJ0eSB2YWx1ZS4gSWYgdGhlIGZ1bmN0aW9uIHJldHVybnMgYSB0cnV0aHkgdmFsdWUsIHRoZW4gdGhlCiAgICAgKiBpdGVyYXRpb24gaXMgc3RvcHBlZC4KICAgICAqLwogICAgZnVuY3Rpb24gZWFjaFByb3Aob2JqLCBmdW5jKSB7CiAgICAgICAgdmFyIHByb3A7CiAgICAgICAgZm9yIChwcm9wIGluIG9iaikgewogICAgICAgICAgICBpZiAoaGFzUHJvcChvYmosIHByb3ApKSB7CiAgICAgICAgICAgICAgICBpZiAoZnVuYyhvYmpbcHJvcF0sIHByb3ApKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBTaW1wbGUgZnVuY3Rpb24gdG8gbWl4IGluIHByb3BlcnRpZXMgZnJvbSBzb3VyY2UgaW50byB0YXJnZXQsCiAgICAgKiBidXQgb25seSBpZiB0YXJnZXQgZG9lcyBub3QgYWxyZWFkeSBoYXZlIGEgcHJvcGVydHkgb2YgdGhlIHNhbWUgbmFtZS4KICAgICAqLwogICAgZnVuY3Rpb24gbWl4aW4odGFyZ2V0LCBzb3VyY2UsIGZvcmNlLCBkZWVwU3RyaW5nTWl4aW4pIHsKICAgICAgICBpZiAoc291cmNlKSB7CiAgICAgICAgICAgIGVhY2hQcm9wKHNvdXJjZSwgZnVuY3Rpb24gKHZhbHVlLCBwcm9wKSB7CiAgICAgICAgICAgICAgICBpZiAoZm9yY2UgfHwgIWhhc1Byb3AodGFyZ2V0LCBwcm9wKSkgewogICAgICAgICAgICAgICAgICAgIGlmIChkZWVwU3RyaW5nTWl4aW4gJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJgogICAgICAgICAgICAgICAgICAgICAgICAhaXNBcnJheSh2YWx1ZSkgJiYgIWlzRnVuY3Rpb24odmFsdWUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICEodmFsdWUgaW5zdGFuY2VvZiBSZWdFeHApKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRhcmdldFtwcm9wXSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BdID0ge307CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgbWl4aW4odGFyZ2V0W3Byb3BdLCB2YWx1ZSwgZm9yY2UsIGRlZXBTdHJpbmdNaXhpbik7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BdID0gdmFsdWU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHRhcmdldDsKICAgIH0KCiAgICAvL1NpbWlsYXIgdG8gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQsIGJ1dCB0aGUgJ3RoaXMnIG9iamVjdCBpcyBzcGVjaWZpZWQKICAgIC8vZmlyc3QsIHNpbmNlIGl0IGlzIGVhc2llciB0byByZWFkL2ZpZ3VyZSBvdXQgd2hhdCAndGhpcycgd2lsbCBiZS4KICAgIGZ1bmN0aW9uIGJpbmQob2JqLCBmbikgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShvYmosIGFyZ3VtZW50cyk7CiAgICAgICAgfTsKICAgIH0KCiAgICBmdW5jdGlvbiBzY3JpcHRzKCkgewogICAgICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7CiAgICB9CgogICAgZnVuY3Rpb24gZGVmYXVsdE9uRXJyb3IoZXJyKSB7CiAgICAgICAgdGhyb3cgZXJyOwogICAgfQoKICAgIC8vQWxsb3cgZ2V0dGluZyBhIGdsb2JhbCB0aGF0IGlzIGV4cHJlc3NlZCBpbgogICAgLy9kb3Qgbm90YXRpb24sIGxpa2UgJ2EuYi5jJy4KICAgIGZ1bmN0aW9uIGdldEdsb2JhbCh2YWx1ZSkgewogICAgICAgIGlmICghdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICAgIH0KICAgICAgICB2YXIgZyA9IGdsb2JhbDsKICAgICAgICBlYWNoKHZhbHVlLnNwbGl0KCcuJyksIGZ1bmN0aW9uIChwYXJ0KSB7CiAgICAgICAgICAgIGcgPSBnW3BhcnRdOwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBnOwogICAgfQoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhbiBlcnJvciB3aXRoIGEgcG9pbnRlciB0byBhbiBVUkwgd2l0aCBtb3JlIGluZm9ybWF0aW9uLgogICAgICogQHBhcmFtIHtTdHJpbmd9IGlkIHRoZSBlcnJvciBJRCB0aGF0IG1hcHMgdG8gYW4gSUQgb24gYSB3ZWIgcGFnZS4KICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlIGh1bWFuIHJlYWRhYmxlIGVycm9yLgogICAgICogQHBhcmFtIHtFcnJvcn0gW2Vycl0gdGhlIG9yaWdpbmFsIGVycm9yLCBpZiB0aGVyZSBpcyBvbmUuCiAgICAgKgogICAgICogQHJldHVybnMge0Vycm9yfQogICAgICovCiAgICBmdW5jdGlvbiBtYWtlRXJyb3IoaWQsIG1zZywgZXJyLCByZXF1aXJlTW9kdWxlcykgewogICAgICAgIHZhciBlID0gbmV3IEVycm9yKG1zZyArICdcbmh0dHA6Ly9yZXF1aXJlanMub3JnL2RvY3MvZXJyb3JzLmh0bWwjJyArIGlkKTsKICAgICAgICBlLnJlcXVpcmVUeXBlID0gaWQ7CiAgICAgICAgZS5yZXF1aXJlTW9kdWxlcyA9IHJlcXVpcmVNb2R1bGVzOwogICAgICAgIGlmIChlcnIpIHsKICAgICAgICAgICAgZS5vcmlnaW5hbEVycm9yID0gZXJyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZTsKICAgIH0KCiAgICBpZiAodHlwZW9mIGRlZmluZSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAvL0lmIGEgZGVmaW5lIGlzIGFscmVhZHkgaW4gcGxheSB2aWEgYW5vdGhlciBBTUQgbG9hZGVyLAogICAgICAgIC8vZG8gbm90IG92ZXJ3cml0ZS4KICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHR5cGVvZiByZXF1aXJlanMgIT09ICd1bmRlZmluZWQnKSB7CiAgICAgICAgaWYgKGlzRnVuY3Rpb24ocmVxdWlyZWpzKSkgewogICAgICAgICAgICAvL0RvIG5vdCBvdmVyd3JpdGUgYW4gZXhpc3RpbmcgcmVxdWlyZWpzIGluc3RhbmNlLgogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGNmZyA9IHJlcXVpcmVqczsKICAgICAgICByZXF1aXJlanMgPSB1bmRlZmluZWQ7CiAgICB9CgogICAgLy9BbGxvdyBmb3IgYSByZXF1aXJlIGNvbmZpZyBvYmplY3QKICAgIGlmICh0eXBlb2YgcmVxdWlyZSAhPT0gJ3VuZGVmaW5lZCcgJiYgIWlzRnVuY3Rpb24ocmVxdWlyZSkpIHsKICAgICAgICAvL2Fzc3VtZSBpdCBpcyBhIGNvbmZpZyBvYmplY3QuCiAgICAgICAgY2ZnID0gcmVxdWlyZTsKICAgICAgICByZXF1aXJlID0gdW5kZWZpbmVkOwogICAgfQoKICAgIGZ1bmN0aW9uIG5ld0NvbnRleHQoY29udGV4dE5hbWUpIHsKICAgICAgICB2YXIgaW5DaGVja0xvYWRlZCwgTW9kdWxlLCBjb250ZXh0LCBoYW5kbGVycywKICAgICAgICAgICAgY2hlY2tMb2FkZWRUaW1lb3V0SWQsCiAgICAgICAgICAgIGNvbmZpZyA9IHsKICAgICAgICAgICAgICAgIC8vRGVmYXVsdHMuIERvIG5vdCBzZXQgYSBkZWZhdWx0IGZvciBtYXAKICAgICAgICAgICAgICAgIC8vY29uZmlnIHRvIHNwZWVkIHVwIG5vcm1hbGl6ZSgpLCB3aGljaAogICAgICAgICAgICAgICAgLy93aWxsIHJ1biBmYXN0ZXIgaWYgdGhlcmUgaXMgbm8gZGVmYXVsdC4KICAgICAgICAgICAgICAgIHdhaXRTZWNvbmRzOiA3LAogICAgICAgICAgICAgICAgYmFzZVVybDogJy4vJywKICAgICAgICAgICAgICAgIHBhdGhzOiB7fSwKICAgICAgICAgICAgICAgIGJ1bmRsZXM6IHt9LAogICAgICAgICAgICAgICAgcGtnczoge30sCiAgICAgICAgICAgICAgICBzaGltOiB7fSwKICAgICAgICAgICAgICAgIGNvbmZpZzoge30KICAgICAgICAgICAgfSwKICAgICAgICAgICAgcmVnaXN0cnkgPSB7fSwKICAgICAgICAgICAgLy9yZWdpc3RyeSBvZiBqdXN0IGVuYWJsZWQgbW9kdWxlcywgdG8gc3BlZWQKICAgICAgICAgICAgLy9jeWNsZSBicmVha2luZyBjb2RlIHdoZW4gbG90cyBvZiBtb2R1bGVzCiAgICAgICAgICAgIC8vYXJlIHJlZ2lzdGVyZWQsIGJ1dCBub3QgYWN0aXZhdGVkLgogICAgICAgICAgICBlbmFibGVkUmVnaXN0cnkgPSB7fSwKICAgICAgICAgICAgdW5kZWZFdmVudHMgPSB7fSwKICAgICAgICAgICAgZGVmUXVldWUgPSBbXSwKICAgICAgICAgICAgZGVmaW5lZCA9IHt9LAogICAgICAgICAgICB1cmxGZXRjaGVkID0ge30sCiAgICAgICAgICAgIGJ1bmRsZXNNYXAgPSB7fSwKICAgICAgICAgICAgcmVxdWlyZUNvdW50ZXIgPSAxLAogICAgICAgICAgICB1bm5vcm1hbGl6ZWRDb3VudGVyID0gMTsKCiAgICAgICAgLyoqCiAgICAgICAgICogVHJpbXMgdGhlIC4gYW5kIC4uIGZyb20gYW4gYXJyYXkgb2YgcGF0aCBzZWdtZW50cy4KICAgICAgICAgKiBJdCB3aWxsIGtlZXAgYSBsZWFkaW5nIHBhdGggc2VnbWVudCBpZiBhIC4uIHdpbGwgYmVjb21lCiAgICAgICAgICogdGhlIGZpcnN0IHBhdGggc2VnbWVudCwgdG8gaGVscCB3aXRoIG1vZHVsZSBuYW1lIGxvb2t1cHMsCiAgICAgICAgICogd2hpY2ggYWN0IGxpa2UgcGF0aHMsIGJ1dCBjYW4gYmUgcmVtYXBwZWQuIEJ1dCB0aGUgZW5kIHJlc3VsdCwKICAgICAgICAgKiBhbGwgcGF0aHMgdGhhdCB1c2UgdGhpcyBmdW5jdGlvbiBzaG91bGQgbG9vayBub3JtYWxpemVkLgogICAgICAgICAqIE5PVEU6IHRoaXMgbWV0aG9kIE1PRElGSUVTIHRoZSBpbnB1dCBhcnJheS4KICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnkgdGhlIGFycmF5IG9mIHBhdGggc2VnbWVudHMuCiAgICAgICAgICovCiAgICAgICAgZnVuY3Rpb24gdHJpbURvdHMoYXJ5KSB7CiAgICAgICAgICAgIHZhciBpLCBwYXJ0OwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICBwYXJ0ID0gYXJ5W2ldOwogICAgICAgICAgICAgICAgaWYgKHBhcnQgPT09ICcuJykgewogICAgICAgICAgICAgICAgICAgIGFyeS5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgICAgICAgICAgaSAtPSAxOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0ID09PSAnLi4nKSB7CiAgICAgICAgICAgICAgICAgICAgLy8gSWYgYXQgdGhlIHN0YXJ0LCBvciBwcmV2aW91cyB2YWx1ZSBpcyBzdGlsbCAuLiwKICAgICAgICAgICAgICAgICAgICAvLyBrZWVwIHRoZW0gc28gdGhhdCB3aGVuIGNvbnZlcnRlZCB0byBhIHBhdGggaXQgbWF5CiAgICAgICAgICAgICAgICAgICAgLy8gc3RpbGwgd29yayB3aGVuIGNvbnZlcnRlZCB0byBhIHBhdGgsIGV2ZW4gdGhvdWdoCiAgICAgICAgICAgICAgICAgICAgLy8gYXMgYW4gSUQgaXQgaXMgbGVzcyB0aGFuIGlkZWFsLiBJbiBsYXJnZXIgcG9pbnQKICAgICAgICAgICAgICAgICAgICAvLyByZWxlYXNlcywgbWF5IGJlIGJldHRlciB0byBqdXN0IGtpY2sgb3V0IGFuIGVycm9yLgogICAgICAgICAgICAgICAgICAgIGlmIChpID09PSAwIHx8IChpID09PSAxICYmIGFyeVsyXSA9PT0gJy4uJykgfHwgYXJ5W2kgLSAxXSA9PT0gJy4uJykgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFyeS5zcGxpY2UoaSAtIDEsIDIpOwogICAgICAgICAgICAgICAgICAgICAgICBpIC09IDI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBHaXZlbiBhIHJlbGF0aXZlIG1vZHVsZSBuYW1lLCBsaWtlIC4vc29tZXRoaW5nLCBub3JtYWxpemUgaXQgdG8KICAgICAgICAgKiBhIHJlYWwgbmFtZSB0aGF0IGNhbiBiZSBtYXBwZWQgdG8gYSBwYXRoLgogICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIHRoZSByZWxhdGl2ZSBuYW1lCiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGJhc2VOYW1lIGEgcmVhbCBuYW1lIHRoYXQgdGhlIG5hbWUgYXJnIGlzIHJlbGF0aXZlCiAgICAgICAgICogdG8uCiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBhcHBseU1hcCBhcHBseSB0aGUgbWFwIGNvbmZpZyB0byB0aGUgdmFsdWUuIFNob3VsZAogICAgICAgICAqIG9ubHkgYmUgZG9uZSBpZiB0aGlzIG5vcm1hbGl6YXRpb24gaXMgZm9yIGEgZGVwZW5kZW5jeSBJRC4KICAgICAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBub3JtYWxpemVkIG5hbWUKICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBub3JtYWxpemUobmFtZSwgYmFzZU5hbWUsIGFwcGx5TWFwKSB7CiAgICAgICAgICAgIHZhciBwa2dNYWluLCBtYXBWYWx1ZSwgbmFtZVBhcnRzLCBpLCBqLCBuYW1lU2VnbWVudCwgbGFzdEluZGV4LAogICAgICAgICAgICAgICAgZm91bmRNYXAsIGZvdW5kSSwgZm91bmRTdGFyTWFwLCBzdGFySSwgbm9ybWFsaXplZEJhc2VQYXJ0cywKICAgICAgICAgICAgICAgIGJhc2VQYXJ0cyA9IChiYXNlTmFtZSAmJiBiYXNlTmFtZS5zcGxpdCgnLycpKSwKICAgICAgICAgICAgICAgIG1hcCA9IGNvbmZpZy5tYXAsCiAgICAgICAgICAgICAgICBzdGFyTWFwID0gbWFwICYmIG1hcFsnKiddOwoKICAgICAgICAgICAgLy9BZGp1c3QgYW55IHJlbGF0aXZlIHBhdGhzLgogICAgICAgICAgICBpZiAobmFtZSkgewogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoJy8nKTsKICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG5hbWUubGVuZ3RoIC0gMTsKCiAgICAgICAgICAgICAgICAvLyBJZiB3YW50aW5nIG5vZGUgSUQgY29tcGF0aWJpbGl0eSwgc3RyaXAgLmpzIGZyb20gZW5kCiAgICAgICAgICAgICAgICAvLyBvZiBJRHMuIEhhdmUgdG8gZG8gdGhpcyBoZXJlLCBhbmQgbm90IGluIG5hbWVUb1VybAogICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBub2RlIGFsbG93cyBlaXRoZXIgLmpzIG9yIG5vbiAuanMgdG8gbWFwCiAgICAgICAgICAgICAgICAvLyB0byBzYW1lIGZpbGUuCiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm5vZGVJZENvbXBhdCAmJiBqc1N1ZmZpeFJlZ0V4cC50ZXN0KG5hbWVbbGFzdEluZGV4XSkpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lW2xhc3RJbmRleF0gPSBuYW1lW2xhc3RJbmRleF0ucmVwbGFjZShqc1N1ZmZpeFJlZ0V4cCwgJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFN0YXJ0cyB3aXRoIGEgJy4nIHNvIG5lZWQgdGhlIGJhc2VOYW1lCiAgICAgICAgICAgICAgICBpZiAobmFtZVswXS5jaGFyQXQoMCkgPT09ICcuJyAmJiBiYXNlUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAvL0NvbnZlcnQgYmFzZU5hbWUgdG8gYXJyYXksIGFuZCBsb3Agb2ZmIHRoZSBsYXN0IHBhcnQsCiAgICAgICAgICAgICAgICAgICAgLy9zbyB0aGF0IC4gbWF0Y2hlcyB0aGF0ICdkaXJlY3RvcnknIGFuZCBub3QgbmFtZSBvZiB0aGUgYmFzZU5hbWUncwogICAgICAgICAgICAgICAgICAgIC8vbW9kdWxlLiBGb3IgaW5zdGFuY2UsIGJhc2VOYW1lIG9mICdvbmUvdHdvL3RocmVlJywgbWFwcyB0bwogICAgICAgICAgICAgICAgICAgIC8vJ29uZS90d28vdGhyZWUuanMnLCBidXQgd2Ugd2FudCB0aGUgZGlyZWN0b3J5LCAnb25lL3R3bycgZm9yCiAgICAgICAgICAgICAgICAgICAgLy90aGlzIG5vcm1hbGl6YXRpb24uCiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZEJhc2VQYXJ0cyA9IGJhc2VQYXJ0cy5zbGljZSgwLCBiYXNlUGFydHMubGVuZ3RoIC0gMSk7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG5vcm1hbGl6ZWRCYXNlUGFydHMuY29uY2F0KG5hbWUpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHRyaW1Eb3RzKG5hbWUpOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuam9pbignLycpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL0FwcGx5IG1hcCBjb25maWcgaWYgYXZhaWxhYmxlLgogICAgICAgICAgICBpZiAoYXBwbHlNYXAgJiYgbWFwICYmIChiYXNlUGFydHMgfHwgc3Rhck1hcCkpIHsKICAgICAgICAgICAgICAgIG5hbWVQYXJ0cyA9IG5hbWUuc3BsaXQoJy8nKTsKCiAgICAgICAgICAgICAgICBvdXRlckxvb3A6IGZvciAoaSA9IG5hbWVQYXJ0cy5sZW5ndGg7IGkgPiAwOyBpIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lU2VnbWVudCA9IG5hbWVQYXJ0cy5zbGljZSgwLCBpKS5qb2luKCcvJyk7CgogICAgICAgICAgICAgICAgICAgIGlmIChiYXNlUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9GaW5kIHRoZSBsb25nZXN0IGJhc2VOYW1lIHNlZ21lbnQgbWF0Y2ggaW4gdGhlIGNvbmZpZy4KICAgICAgICAgICAgICAgICAgICAgICAgLy9TbywgZG8gam9pbnMgb24gdGhlIGJpZ2dlc3QgdG8gc21hbGxlc3QgbGVuZ3RocyBvZiBiYXNlUGFydHMuCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IGJhc2VQYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFZhbHVlID0gZ2V0T3duKG1hcCwgYmFzZVBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy8nKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9iYXNlTmFtZSBzZWdtZW50IGhhcyBjb25maWcsIGZpbmQgaWYgaXQgaGFzIG9uZSBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBuYW1lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hcFZhbHVlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBnZXRPd24obWFwVmFsdWUsIG5hbWVTZWdtZW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFwVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9NYXRjaCwgdXBkYXRlIG5hbWUgdG8gdGhlIG5ldyB2YWx1ZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRNYXAgPSBtYXBWYWx1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRJID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXJMb29wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9DaGVjayBmb3IgYSBzdGFyIG1hcCBtYXRjaCwgYnV0IGp1c3QgaG9sZCBvbiB0byBpdCwKICAgICAgICAgICAgICAgICAgICAvL2lmIHRoZXJlIGlzIGEgc2hvcnRlciBzZWdtZW50IG1hdGNoIGxhdGVyIGluIGEgbWF0Y2hpbmcKICAgICAgICAgICAgICAgICAgICAvL2NvbmZpZywgdGhlbiBmYXZvciBvdmVyIHRoaXMgc3RhciBtYXAuCiAgICAgICAgICAgICAgICAgICAgaWYgKCFmb3VuZFN0YXJNYXAgJiYgc3Rhck1hcCAmJiBnZXRPd24oc3Rhck1hcCwgbmFtZVNlZ21lbnQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kU3Rhck1hcCA9IGdldE93bihzdGFyTWFwLCBuYW1lU2VnbWVudCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJJID0gaTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFmb3VuZE1hcCAmJiBmb3VuZFN0YXJNYXApIHsKICAgICAgICAgICAgICAgICAgICBmb3VuZE1hcCA9IGZvdW5kU3Rhck1hcDsKICAgICAgICAgICAgICAgICAgICBmb3VuZEkgPSBzdGFySTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZm91bmRNYXApIHsKICAgICAgICAgICAgICAgICAgICBuYW1lUGFydHMuc3BsaWNlKDAsIGZvdW5kSSwgZm91bmRNYXApOwogICAgICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lUGFydHMuam9pbignLycpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJZiB0aGUgbmFtZSBwb2ludHMgdG8gYSBwYWNrYWdlJ3MgbmFtZSwgdXNlCiAgICAgICAgICAgIC8vIHRoZSBwYWNrYWdlIG1haW4gaW5zdGVhZC4KICAgICAgICAgICAgcGtnTWFpbiA9IGdldE93bihjb25maWcucGtncywgbmFtZSk7CgogICAgICAgICAgICByZXR1cm4gcGtnTWFpbiA/IHBrZ01haW4gOiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlU2NyaXB0KG5hbWUpIHsKICAgICAgICAgICAgaWYgKGlzQnJvd3NlcikgewogICAgICAgICAgICAgICAgZWFjaChzY3JpcHRzKCksIGZ1bmN0aW9uIChzY3JpcHROb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdE5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLXJlcXVpcmVtb2R1bGUnKSA9PT0gbmFtZSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0Tm9kZS5nZXRBdHRyaWJ1dGUoJ2RhdGEtcmVxdWlyZWNvbnRleHQnKSA9PT0gY29udGV4dC5jb250ZXh0TmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHROb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2NyaXB0Tm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBoYXNQYXRoRmFsbGJhY2soaWQpIHsKICAgICAgICAgICAgdmFyIHBhdGhDb25maWcgPSBnZXRPd24oY29uZmlnLnBhdGhzLCBpZCk7CiAgICAgICAgICAgIGlmIChwYXRoQ29uZmlnICYmIGlzQXJyYXkocGF0aENvbmZpZykgJiYgcGF0aENvbmZpZy5sZW5ndGggPiAxKSB7CiAgICAgICAgICAgICAgICAvL1BvcCBvZmYgdGhlIGZpcnN0IGFycmF5IHZhbHVlLCBzaW5jZSBpdCBmYWlsZWQsIGFuZAogICAgICAgICAgICAgICAgLy9yZXRyeQogICAgICAgICAgICAgICAgcGF0aENvbmZpZy5zaGlmdCgpOwogICAgICAgICAgICAgICAgY29udGV4dC5yZXF1aXJlLnVuZGVmKGlkKTsKCiAgICAgICAgICAgICAgICAvL0N1c3RvbSByZXF1aXJlIHRoYXQgZG9lcyBub3QgZG8gbWFwIHRyYW5zbGF0aW9uLCBzaW5jZQogICAgICAgICAgICAgICAgLy9JRCBpcyAiYWJzb2x1dGUiLCBhbHJlYWR5IG1hcHBlZC9yZXNvbHZlZC4KICAgICAgICAgICAgICAgIGNvbnRleHQubWFrZVJlcXVpcmUobnVsbCwgewogICAgICAgICAgICAgICAgICAgIHNraXBNYXA6IHRydWUKICAgICAgICAgICAgICAgIH0pKFtpZF0pOwoKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1R1cm5zIGEgcGx1Z2luIXJlc291cmNlIHRvIFtwbHVnaW4sIHJlc291cmNlXQogICAgICAgIC8vd2l0aCB0aGUgcGx1Z2luIGJlaW5nIHVuZGVmaW5lZCBpZiB0aGUgbmFtZQogICAgICAgIC8vZGlkIG5vdCBoYXZlIGEgcGx1Z2luIHByZWZpeC4KICAgICAgICBmdW5jdGlvbiBzcGxpdFByZWZpeChuYW1lKSB7CiAgICAgICAgICAgIHZhciBwcmVmaXgsCiAgICAgICAgICAgICAgICBpbmRleCA9IG5hbWUgPyBuYW1lLmluZGV4T2YoJyEnKSA6IC0xOwogICAgICAgICAgICBpZiAoaW5kZXggPiAtMSkgewogICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSwgbmFtZS5sZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBbcHJlZml4LCBuYW1lXTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgYSBtb2R1bGUgbWFwcGluZyB0aGF0IGluY2x1ZGVzIHBsdWdpbiBwcmVmaXgsIG1vZHVsZQogICAgICAgICAqIG5hbWUsIGFuZCBwYXRoLiBJZiBwYXJlbnRNb2R1bGVNYXAgaXMgcHJvdmlkZWQgaXQgd2lsbAogICAgICAgICAqIGFsc28gbm9ybWFsaXplIHRoZSBuYW1lIHZpYSByZXF1aXJlLm5vcm1hbGl6ZSgpCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSB0aGUgbW9kdWxlIG5hbWUKICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gW3BhcmVudE1vZHVsZU1hcF0gcGFyZW50IG1vZHVsZSBtYXAKICAgICAgICAgKiBmb3IgdGhlIG1vZHVsZSBuYW1lLCB1c2VkIHRvIHJlc29sdmUgcmVsYXRpdmUgbmFtZXMuCiAgICAgICAgICogQHBhcmFtIHtCb29sZWFufSBpc05vcm1hbGl6ZWQ6IGlzIHRoZSBJRCBhbHJlYWR5IG5vcm1hbGl6ZWQuCiAgICAgICAgICogVGhpcyBpcyB0cnVlIGlmIHRoaXMgY2FsbCBpcyBkb25lIGZvciBhIGRlZmluZSgpIG1vZHVsZSBJRC4KICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGFwcGx5TWFwOiBhcHBseSB0aGUgbWFwIGNvbmZpZyB0byB0aGUgSUQuCiAgICAgICAgICogU2hvdWxkIG9ubHkgYmUgdHJ1ZSBpZiB0aGlzIG1hcCBpcyBmb3IgYSBkZXBlbmRlbmN5LgogICAgICAgICAqCiAgICAgICAgICogQHJldHVybnMge09iamVjdH0KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiBtYWtlTW9kdWxlTWFwKG5hbWUsIHBhcmVudE1vZHVsZU1hcCwgaXNOb3JtYWxpemVkLCBhcHBseU1hcCkgewogICAgICAgICAgICB2YXIgdXJsLCBwbHVnaW5Nb2R1bGUsIHN1ZmZpeCwgbmFtZVBhcnRzLAogICAgICAgICAgICAgICAgcHJlZml4ID0gbnVsbCwKICAgICAgICAgICAgICAgIHBhcmVudE5hbWUgPSBwYXJlbnRNb2R1bGVNYXAgPyBwYXJlbnRNb2R1bGVNYXAubmFtZSA6IG51bGwsCiAgICAgICAgICAgICAgICBvcmlnaW5hbE5hbWUgPSBuYW1lLAogICAgICAgICAgICAgICAgaXNEZWZpbmUgPSB0cnVlLAogICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUgPSAnJzsKCiAgICAgICAgICAgIC8vSWYgbm8gbmFtZSwgdGhlbiBpdCBtZWFucyBpdCBpcyBhIHJlcXVpcmUgY2FsbCwgZ2VuZXJhdGUgYW4KICAgICAgICAgICAgLy9pbnRlcm5hbCBuYW1lLgogICAgICAgICAgICBpZiAoIW5hbWUpIHsKICAgICAgICAgICAgICAgIGlzRGVmaW5lID0gZmFsc2U7CiAgICAgICAgICAgICAgICBuYW1lID0gJ19AcicgKyAocmVxdWlyZUNvdW50ZXIgKz0gMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG5hbWVQYXJ0cyA9IHNwbGl0UHJlZml4KG5hbWUpOwogICAgICAgICAgICBwcmVmaXggPSBuYW1lUGFydHNbMF07CiAgICAgICAgICAgIG5hbWUgPSBuYW1lUGFydHNbMV07CgogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBwcmVmaXggPSBub3JtYWxpemUocHJlZml4LCBwYXJlbnROYW1lLCBhcHBseU1hcCk7CiAgICAgICAgICAgICAgICBwbHVnaW5Nb2R1bGUgPSBnZXRPd24oZGVmaW5lZCwgcHJlZml4KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9BY2NvdW50IGZvciByZWxhdGl2ZSBwYXRocyBpZiB0aGVyZSBpcyBhIGJhc2UgbmFtZS4KICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgICAgICAgICBpZiAocGx1Z2luTW9kdWxlICYmIHBsdWdpbk1vZHVsZS5ub3JtYWxpemUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9QbHVnaW4gaXMgbG9hZGVkLCB1c2UgaXRzIG5vcm1hbGl6ZSBtZXRob2QuCiAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gcGx1Z2luTW9kdWxlLm5vcm1hbGl6ZShuYW1lLCBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZShuYW1lLCBwYXJlbnROYW1lLCBhcHBseU1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIG5lc3RlZCBwbHVnaW4gcmVmZXJlbmNlcywgdGhlbiBkbyBub3QgdHJ5IHRvCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSwgYXMgaXQgd2lsbCBub3Qgbm9ybWFsaXplIGNvcnJlY3RseS4gVGhpcwogICAgICAgICAgICAgICAgICAgICAgICAvLyBwbGFjZXMgYSByZXN0cmljdGlvbiBvbiByZXNvdXJjZUlkcywgYW5kIHRoZSBsb25nZXIKICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGVybSBzb2x1dGlvbiBpcyBub3QgdG8gbm9ybWFsaXplIHVudGlsIHBsdWdpbnMgYXJlCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvYWRlZCBhbmQgYWxsIG5vcm1hbGl6YXRpb25zIHRvIGFsbG93IGZvciBhc3luYwogICAgICAgICAgICAgICAgICAgICAgICAvLyBsb2FkaW5nIG9mIGEgbG9hZGVyIHBsdWdpbi4gQnV0IGZvciBub3csIGZpeGVzIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAvLyBjb21tb24gdXNlcy4gRGV0YWlscyBpbiAjMTEzMQogICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTmFtZSA9IG5hbWUuaW5kZXhPZignIScpID09PSAtMSA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplKG5hbWUsIHBhcmVudE5hbWUsIGFwcGx5TWFwKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vQSByZWd1bGFyIG1vZHVsZS4KICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTmFtZSA9IG5vcm1hbGl6ZShuYW1lLCBwYXJlbnROYW1lLCBhcHBseU1hcCk7CgogICAgICAgICAgICAgICAgICAgIC8vTm9ybWFsaXplZCBuYW1lIG1heSBiZSBhIHBsdWdpbiBJRCBkdWUgdG8gbWFwIGNvbmZpZwogICAgICAgICAgICAgICAgICAgIC8vYXBwbGljYXRpb24gaW4gbm9ybWFsaXplLiBUaGUgbWFwIGNvbmZpZyB2YWx1ZXMgbXVzdAogICAgICAgICAgICAgICAgICAgIC8vYWxyZWFkeSBiZSBub3JtYWxpemVkLCBzbyBkbyBub3QgbmVlZCB0byByZWRvIHRoYXQgcGFydC4KICAgICAgICAgICAgICAgICAgICBuYW1lUGFydHMgPSBzcGxpdFByZWZpeChub3JtYWxpemVkTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gbmFtZVBhcnRzWzBdOwogICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gbmFtZVBhcnRzWzFdOwogICAgICAgICAgICAgICAgICAgIGlzTm9ybWFsaXplZCA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgIHVybCA9IGNvbnRleHQubmFtZVRvVXJsKG5vcm1hbGl6ZWROYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9JZiB0aGUgaWQgaXMgYSBwbHVnaW4gaWQgdGhhdCBjYW5ub3QgYmUgZGV0ZXJtaW5lZCBpZiBpdCBuZWVkcwogICAgICAgICAgICAvL25vcm1hbGl6YXRpb24sIHN0YW1wIGl0IHdpdGggYSB1bmlxdWUgSUQgc28gdHdvIG1hdGNoaW5nIHJlbGF0aXZlCiAgICAgICAgICAgIC8vaWRzIHRoYXQgbWF5IGNvbmZsaWN0IGNhbiBiZSBzZXBhcmF0ZS4KICAgICAgICAgICAgc3VmZml4ID0gcHJlZml4ICYmICFwbHVnaW5Nb2R1bGUgJiYgIWlzTm9ybWFsaXplZCA/CiAgICAgICAgICAgICAgICAgICAgICdfdW5ub3JtYWxpemVkJyArICh1bm5vcm1hbGl6ZWRDb3VudGVyICs9IDEpIDoKICAgICAgICAgICAgICAgICAgICAgJyc7CgogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgcHJlZml4OiBwcmVmaXgsCiAgICAgICAgICAgICAgICBuYW1lOiBub3JtYWxpemVkTmFtZSwKICAgICAgICAgICAgICAgIHBhcmVudE1hcDogcGFyZW50TW9kdWxlTWFwLAogICAgICAgICAgICAgICAgdW5ub3JtYWxpemVkOiAhIXN1ZmZpeCwKICAgICAgICAgICAgICAgIHVybDogdXJsLAogICAgICAgICAgICAgICAgb3JpZ2luYWxOYW1lOiBvcmlnaW5hbE5hbWUsCiAgICAgICAgICAgICAgICBpc0RlZmluZTogaXNEZWZpbmUsCiAgICAgICAgICAgICAgICBpZDogKHByZWZpeCA/CiAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCArICchJyArIG5vcm1hbGl6ZWROYW1lIDoKICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE5hbWUpICsgc3VmZml4CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBnZXRNb2R1bGUoZGVwTWFwKSB7CiAgICAgICAgICAgIHZhciBpZCA9IGRlcE1hcC5pZCwKICAgICAgICAgICAgICAgIG1vZCA9IGdldE93bihyZWdpc3RyeSwgaWQpOwoKICAgICAgICAgICAgaWYgKCFtb2QpIHsKICAgICAgICAgICAgICAgIG1vZCA9IHJlZ2lzdHJ5W2lkXSA9IG5ldyBjb250ZXh0Lk1vZHVsZShkZXBNYXApOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbW9kOwogICAgICAgIH0KCiAgICAgICAgZnVuY3Rpb24gb24oZGVwTWFwLCBuYW1lLCBmbikgewogICAgICAgICAgICB2YXIgaWQgPSBkZXBNYXAuaWQsCiAgICAgICAgICAgICAgICBtb2QgPSBnZXRPd24ocmVnaXN0cnksIGlkKTsKCiAgICAgICAgICAgIGlmIChoYXNQcm9wKGRlZmluZWQsIGlkKSAmJgogICAgICAgICAgICAgICAgICAgICghbW9kIHx8IG1vZC5kZWZpbmVFbWl0Q29tcGxldGUpKSB7CiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gJ2RlZmluZWQnKSB7CiAgICAgICAgICAgICAgICAgICAgZm4oZGVmaW5lZFtpZF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbW9kID0gZ2V0TW9kdWxlKGRlcE1hcCk7CiAgICAgICAgICAgICAgICBpZiAobW9kLmVycm9yICYmIG5hbWUgPT09ICdlcnJvcicpIHsKICAgICAgICAgICAgICAgICAgICBmbihtb2QuZXJyb3IpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBtb2Qub24obmFtZSwgZm4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBvbkVycm9yKGVyciwgZXJyYmFjaykgewogICAgICAgICAgICB2YXIgaWRzID0gZXJyLnJlcXVpcmVNb2R1bGVzLAogICAgICAgICAgICAgICAgbm90aWZpZWQgPSBmYWxzZTsKCiAgICAgICAgICAgIGlmIChlcnJiYWNrKSB7CiAgICAgICAgICAgICAgICBlcnJiYWNrKGVycik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBlYWNoKGlkcywgZnVuY3Rpb24gKGlkKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIG1vZCA9IGdldE93bihyZWdpc3RyeSwgaWQpOwogICAgICAgICAgICAgICAgICAgIGlmIChtb2QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9TZXQgZXJyb3Igb24gbW9kdWxlLCBzbyBpdCBza2lwcyB0aW1lb3V0IGNoZWNrcy4KICAgICAgICAgICAgICAgICAgICAgICAgbW9kLmVycm9yID0gZXJyOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobW9kLmV2ZW50cy5lcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZpZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kLmVtaXQoJ2Vycm9yJywgZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIGlmICghbm90aWZpZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXEub25FcnJvcihlcnIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gdHJhbnNmZXIgZ2xvYmFsUXVldWUgaXRlbXMgdG8gdGhpcyBjb250ZXh0J3MKICAgICAgICAgKiBkZWZRdWV1ZS4KICAgICAgICAgKi8KICAgICAgICBmdW5jdGlvbiB0YWtlR2xvYmFsUXVldWUoKSB7CiAgICAgICAgICAgIC8vUHVzaCBhbGwgdGhlIGdsb2JhbERlZlF1ZXVlIGl0ZW1zIGludG8gdGhlIGNvbnRleHQncyBkZWZRdWV1ZQogICAgICAgICAgICBpZiAoZ2xvYmFsRGVmUXVldWUubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICBlYWNoKGdsb2JhbERlZlF1ZXVlLCBmdW5jdGlvbihxdWV1ZUl0ZW0pIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSBxdWV1ZUl0ZW1bMF07CiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpZCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5kZWZRdWV1ZU1hcFtpZF0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkZWZRdWV1ZS5wdXNoKHF1ZXVlSXRlbSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGdsb2JhbERlZlF1ZXVlID0gW107CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGhhbmRsZXJzID0gewogICAgICAgICAgICAncmVxdWlyZSc6IGZ1bmN0aW9uIChtb2QpIHsKICAgICAgICAgICAgICAgIGlmIChtb2QucmVxdWlyZSkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBtb2QucmVxdWlyZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChtb2QucmVxdWlyZSA9IGNvbnRleHQubWFrZVJlcXVpcmUobW9kLm1hcCkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAnZXhwb3J0cyc6IGZ1bmN0aW9uIChtb2QpIHsKICAgICAgICAgICAgICAgIG1vZC51c2luZ0V4cG9ydHMgPSB0cnVlOwogICAgICAgICAgICAgICAgaWYgKG1vZC5tYXAuaXNEZWZpbmUpIHsKICAgICAgICAgICAgICAgICAgICBpZiAobW9kLmV4cG9ydHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChkZWZpbmVkW21vZC5tYXAuaWRdID0gbW9kLmV4cG9ydHMpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAobW9kLmV4cG9ydHMgPSBkZWZpbmVkW21vZC5tYXAuaWRdID0ge30pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgJ21vZHVsZSc6IGZ1bmN0aW9uIChtb2QpIHsKICAgICAgICAgICAgICAgIGlmIChtb2QubW9kdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1vZC5tb2R1bGU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAobW9kLm1vZHVsZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgaWQ6IG1vZC5tYXAuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHVyaTogbW9kLm1hcC51cmwsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZzogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdldE93bihjb25maWcuY29uZmlnLCBtb2QubWFwLmlkKSB8fCB7fTsKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0czogbW9kLmV4cG9ydHMgfHwgKG1vZC5leHBvcnRzID0ge30pCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBmdW5jdGlvbiBjbGVhblJlZ2lzdHJ5KGlkKSB7CiAgICAgICAgICAgIC8vQ2xlYW4gdXAgbWFjaGluZXJ5IHVzZWQgZm9yIHdhaXRpbmcgbW9kdWxlcy4KICAgICAgICAgICAgZGVsZXRlIHJlZ2lzdHJ5W2lkXTsKICAgICAgICAgICAgZGVsZXRlIGVuYWJsZWRSZWdpc3RyeVtpZF07CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBicmVha0N5Y2xlKG1vZCwgdHJhY2VkLCBwcm9jZXNzZWQpIHsKICAgICAgICAgICAgdmFyIGlkID0gbW9kLm1hcC5pZDsKCiAgICAgICAgICAgIGlmIChtb2QuZXJyb3IpIHsKICAgICAgICAgICAgICAgIG1vZC5lbWl0KCdlcnJvcicsIG1vZC5lcnJvcik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0cmFjZWRbaWRdID0gdHJ1ZTsKICAgICAgICAgICAgICAgIGVhY2gobW9kLmRlcE1hcHMsIGZ1bmN0aW9uIChkZXBNYXAsIGkpIHsKICAgICAgICAgICAgICAgICAgICB2YXIgZGVwSWQgPSBkZXBNYXAuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlcCA9IGdldE93bihyZWdpc3RyeSwgZGVwSWQpOwoKICAgICAgICAgICAgICAgICAgICAvL09ubHkgZm9yY2UgdGhpbmdzIHRoYXQgaGF2ZSBub3QgY29tcGxldGVkCiAgICAgICAgICAgICAgICAgICAgLy9iZWluZyBkZWZpbmVkLCBzbyBzdGlsbCBpbiB0aGUgcmVnaXN0cnksCiAgICAgICAgICAgICAgICAgICAgLy9hbmQgb25seSBpZiBpdCBoYXMgbm90IGJlZW4gbWF0Y2hlZCB1cAogICAgICAgICAgICAgICAgICAgIC8vaW4gdGhlIG1vZHVsZSBhbHJlYWR5LgogICAgICAgICAgICAgICAgICAgIGlmIChkZXAgJiYgIW1vZC5kZXBNYXRjaGVkW2ldICYmICFwcm9jZXNzZWRbZGVwSWRdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXRPd24odHJhY2VkLCBkZXBJZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZC5kZWZpbmVEZXAoaSwgZGVmaW5lZFtkZXBJZF0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kLmNoZWNrKCk7IC8vcGFzcyBmYWxzZT8KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrQ3ljbGUoZGVwLCB0cmFjZWQsIHByb2Nlc3NlZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIHByb2Nlc3NlZFtpZF0gPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiBjaGVja0xvYWRlZCgpIHsKICAgICAgICAgICAgdmFyIGVyciwgdXNpbmdQYXRoRmFsbGJhY2ssCiAgICAgICAgICAgICAgICB3YWl0SW50ZXJ2YWwgPSBjb25maWcud2FpdFNlY29uZHMgKiAxMDAwLAogICAgICAgICAgICAgICAgLy9JdCBpcyBwb3NzaWJsZSB0byBkaXNhYmxlIHRoZSB3YWl0IGludGVydmFsIGJ5IHVzaW5nIHdhaXRTZWNvbmRzIG9mIDAuCiAgICAgICAgICAgICAgICBleHBpcmVkID0gd2FpdEludGVydmFsICYmIChjb250ZXh0LnN0YXJ0VGltZSArIHdhaXRJbnRlcnZhbCkgPCBuZXcgRGF0ZSgpLmdldFRpbWUoKSwKICAgICAgICAgICAgICAgIG5vTG9hZHMgPSBbXSwKICAgICAgICAgICAgICAgIHJlcUNhbGxzID0gW10sCiAgICAgICAgICAgICAgICBzdGlsbExvYWRpbmcgPSBmYWxzZSwKICAgICAgICAgICAgICAgIG5lZWRDeWNsZUNoZWNrID0gdHJ1ZTsKCiAgICAgICAgICAgIC8vRG8gbm90IGJvdGhlciBpZiB0aGlzIGNhbGwgd2FzIGEgcmVzdWx0IG9mIGEgY3ljbGUgYnJlYWsuCiAgICAgICAgICAgIGlmIChpbkNoZWNrTG9hZGVkKSB7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGluQ2hlY2tMb2FkZWQgPSB0cnVlOwoKICAgICAgICAgICAgLy9GaWd1cmUgb3V0IHRoZSBzdGF0ZSBvZiBhbGwgdGhlIG1vZHVsZXMuCiAgICAgICAgICAgIGVhY2hQcm9wKGVuYWJsZWRSZWdpc3RyeSwgZnVuY3Rpb24gKG1vZCkgewogICAgICAgICAgICAgICAgdmFyIG1hcCA9IG1vZC5tYXAsCiAgICAgICAgICAgICAgICAgICAgbW9kSWQgPSBtYXAuaWQ7CgogICAgICAgICAgICAgICAgLy9Ta2lwIHRoaW5ncyB0aGF0IGFyZSBub3QgZW5hYmxlZCBvciBpbiBlcnJvciBzdGF0ZS4KICAgICAgICAgICAgICAgIGlmICghbW9kLmVuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFtYXAuaXNEZWZpbmUpIHsKICAgICAgICAgICAgICAgICAgICByZXFDYWxscy5wdXNoKG1vZCk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKCFtb2QuZXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAvL0lmIHRoZSBtb2R1bGUgc2hvdWxkIGJlIGV4ZWN1dGVkLCBhbmQgaXQgaGFzIG5vdAogICAgICAgICAgICAgICAgICAgIC8vYmVlbiBpbml0ZWQgYW5kIHRpbWUgaXMgdXAsIHJlbWVtYmVyIGl0LgogICAgICAgICAgICAgICAgICAgIGlmICghbW9kLmluaXRlZCAmJiBleHBpcmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNQYXRoRmFsbGJhY2sobW9kSWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZ1BhdGhGYWxsYmFjayA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGlsbExvYWRpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9Mb2Fkcy5wdXNoKG1vZElkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVNjcmlwdChtb2RJZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFtb2QuaW5pdGVkICYmIG1vZC5mZXRjaGVkICYmIG1hcC5pc0RlZmluZSkgewogICAgICAgICAgICAgICAgICAgICAgICBzdGlsbExvYWRpbmcgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW1hcC5wcmVmaXgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vTm8gcmVhc29uIHRvIGtlZXAgbG9va2luZyBmb3IgdW5maW5pc2hlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9sb2FkaW5nLiBJZiB0aGUgb25seSBzdGlsbExvYWRpbmcgaXMgYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9wbHVnaW4gcmVzb3VyY2UgdGhvdWdoLCBrZWVwIGdvaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9iZWNhdXNlIGl0IG1heSBiZSB0aGF0IGEgcGx1Z2luIHJlc291cmNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2lzIHdhaXRpbmcgb24gYSBub24tcGx1Z2luIGN5Y2xlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChuZWVkQ3ljbGVDaGVjayA9IGZhbHNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CgogICAgICAgICAgICBpZiAoZXhwaXJlZCAmJiBub0xvYWRzLmxlbmd0aCkgewogICAgICAgICAgICAgICAgLy9JZiB3YWl0IHRpbWUgZXhwaXJlZCwgdGhyb3cgZXJyb3Igb2YgdW5sb2FkZWQgbW9kdWxlcy4KICAgICAgICAgICAgICAgIGVyciA9IG1ha2VFcnJvcigndGltZW91dCcsICdMb2FkIHRpbWVvdXQgZm9yIG1vZHVsZXM6ICcgKyBub0xvYWRzLCBudWxsLCBub0xvYWRzKTsKICAgICAgICAgICAgICAgIGVyci5jb250ZXh0TmFtZSA9IGNvbnRleHQuY29udGV4dE5hbWU7CiAgICAgICAgICAgICAgICByZXR1cm4gb25FcnJvcihlcnIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL05vdCBleHBpcmVkLCBjaGVjayBmb3IgYSBjeWNsZS4KICAgICAgICAgICAgaWYgKG5lZWRDeWNsZUNoZWNrKSB7CiAgICAgICAgICAgICAgICBlYWNoKHJlcUNhbGxzLCBmdW5jdGlvbiAobW9kKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWtDeWNsZShtb2QsIHt9LCB7fSk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9JZiBzdGlsbCB3YWl0aW5nIG9uIGxvYWRzLCBhbmQgdGhlIHdhaXRpbmcgbG9hZCBpcyBzb21ldGhpbmcKICAgICAgICAgICAgLy9vdGhlciB0aGFuIGEgcGx1Z2luIHJlc291cmNlLCBvciB0aGVyZSBhcmUgc3RpbGwgb3V0c3RhbmRpbmcKICAgICAgICAgICAgLy9zY3JpcHRzLCB0aGVuIGp1c3QgdHJ5IGJhY2sgbGF0ZXIuCiAgICAgICAgICAgIGlmICgoIWV4cGlyZWQgfHwgdXNpbmdQYXRoRmFsbGJhY2spICYmIHN0aWxsTG9hZGluZykgewogICAgICAgICAgICAgICAgLy9Tb21ldGhpbmcgaXMgc3RpbGwgd2FpdGluZyB0byBsb2FkLiBXYWl0IGZvciBpdCwgYnV0IG9ubHkKICAgICAgICAgICAgICAgIC8vaWYgYSB0aW1lb3V0IGlzIG5vdCBhbHJlYWR5IGluIGVmZmVjdC4KICAgICAgICAgICAgICAgIGlmICgoaXNCcm93c2VyIHx8IGlzV2ViV29ya2VyKSAmJiAhY2hlY2tMb2FkZWRUaW1lb3V0SWQpIHsKICAgICAgICAgICAgICAgICAgICBjaGVja0xvYWRlZFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICBjaGVja0xvYWRlZFRpbWVvdXRJZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrTG9hZGVkKCk7CiAgICAgICAgICAgICAgICAgICAgfSwgNTApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpbkNoZWNrTG9hZGVkID0gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBNb2R1bGUgPSBmdW5jdGlvbiAobWFwKSB7CiAgICAgICAgICAgIHRoaXMuZXZlbnRzID0gZ2V0T3duKHVuZGVmRXZlbnRzLCBtYXAuaWQpIHx8IHt9OwogICAgICAgICAgICB0aGlzLm1hcCA9IG1hcDsKICAgICAgICAgICAgdGhpcy5zaGltID0gZ2V0T3duKGNvbmZpZy5zaGltLCBtYXAuaWQpOwogICAgICAgICAgICB0aGlzLmRlcEV4cG9ydHMgPSBbXTsKICAgICAgICAgICAgdGhpcy5kZXBNYXBzID0gW107CiAgICAgICAgICAgIHRoaXMuZGVwTWF0Y2hlZCA9IFtdOwogICAgICAgICAgICB0aGlzLnBsdWdpbk1hcHMgPSB7fTsKICAgICAgICAgICAgdGhpcy5kZXBDb3VudCA9IDA7CgogICAgICAgICAgICAvKiB0aGlzLmV4cG9ydHMgdGhpcy5mYWN0b3J5CiAgICAgICAgICAgICAgIHRoaXMuZGVwTWFwcyA9IFtdLAogICAgICAgICAgICAgICB0aGlzLmVuYWJsZWQsIHRoaXMuZmV0Y2hlZAogICAgICAgICAgICAqLwogICAgICAgIH07CgogICAgICAgIE1vZHVsZS5wcm90b3R5cGUgPSB7CiAgICAgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChkZXBNYXBzLCBmYWN0b3J5LCBlcnJiYWNrLCBvcHRpb25zKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgICAgICAgICAgICAgICAvL0RvIG5vdCBkbyBtb3JlIGluaXRzIGlmIGFscmVhZHkgZG9uZS4gQ2FuIGhhcHBlbiBpZiB0aGVyZQogICAgICAgICAgICAgICAgLy9hcmUgbXVsdGlwbGUgZGVmaW5lIGNhbGxzIGZvciB0aGUgc2FtZSBtb2R1bGUuIFRoYXQgaXMgbm90CiAgICAgICAgICAgICAgICAvL2Egbm9ybWFsLCBjb21tb24gY2FzZSwgYnV0IGl0IGlzIGFsc28gbm90IHVuZXhwZWN0ZWQuCiAgICAgICAgICAgICAgICBpZiAodGhpcy5pbml0ZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdGhpcy5mYWN0b3J5ID0gZmFjdG9yeTsKCiAgICAgICAgICAgICAgICBpZiAoZXJyYmFjaykgewogICAgICAgICAgICAgICAgICAgIC8vUmVnaXN0ZXIgZm9yIGVycm9ycyBvbiB0aGlzIG1vZHVsZS4KICAgICAgICAgICAgICAgICAgICB0aGlzLm9uKCdlcnJvcicsIGVycmJhY2spOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmV2ZW50cy5lcnJvcikgewogICAgICAgICAgICAgICAgICAgIC8vSWYgbm8gZXJyYmFjayBhbHJlYWR5LCBidXQgdGhlcmUgYXJlIGVycm9yIGxpc3RlbmVycwogICAgICAgICAgICAgICAgICAgIC8vb24gdGhpcyBtb2R1bGUsIHNldCB1cCBhbiBlcnJiYWNrIHRvIHBhc3MgdG8gdGhlIGRlcHMuCiAgICAgICAgICAgICAgICAgICAgZXJyYmFjayA9IGJpbmQodGhpcywgZnVuY3Rpb24gKGVycikgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0RvIGEgY29weSBvZiB0aGUgZGVwZW5kZW5jeSBhcnJheSwgc28gdGhhdAogICAgICAgICAgICAgICAgLy9zb3VyY2UgaW5wdXRzIGFyZSBub3QgbW9kaWZpZWQuIEZvciBleGFtcGxlCiAgICAgICAgICAgICAgICAvLyJzaGltIiBkZXBzIGFyZSBwYXNzZWQgaW4gaGVyZSBkaXJlY3RseSwgYW5kCiAgICAgICAgICAgICAgICAvL2RvaW5nIGEgZGlyZWN0IG1vZGlmaWNhdGlvbiBvZiB0aGUgZGVwTWFwcyBhcnJheQogICAgICAgICAgICAgICAgLy93b3VsZCBhZmZlY3QgdGhhdCBjb25maWcuCiAgICAgICAgICAgICAgICB0aGlzLmRlcE1hcHMgPSBkZXBNYXBzICYmIGRlcE1hcHMuc2xpY2UoMCk7CgogICAgICAgICAgICAgICAgdGhpcy5lcnJiYWNrID0gZXJyYmFjazsKCiAgICAgICAgICAgICAgICAvL0luZGljYXRlIHRoaXMgbW9kdWxlIGhhcyBiZSBpbml0aWFsaXplZAogICAgICAgICAgICAgICAgdGhpcy5pbml0ZWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgIHRoaXMuaWdub3JlID0gb3B0aW9ucy5pZ25vcmU7CgogICAgICAgICAgICAgICAgLy9Db3VsZCBoYXZlIG9wdGlvbiB0byBpbml0IHRoaXMgbW9kdWxlIGluIGVuYWJsZWQgbW9kZSwKICAgICAgICAgICAgICAgIC8vb3IgY291bGQgaGF2ZSBiZWVuIHByZXZpb3VzbHkgbWFya2VkIGFzIGVuYWJsZWQuIEhvd2V2ZXIsCiAgICAgICAgICAgICAgICAvL3RoZSBkZXBlbmRlbmNpZXMgYXJlIG5vdCBrbm93biB1bnRpbCBpbml0IGlzIGNhbGxlZC4gU28KICAgICAgICAgICAgICAgIC8vaWYgZW5hYmxlZCBwcmV2aW91c2x5LCBub3cgdHJpZ2dlciBkZXBlbmRlbmNpZXMgYXMgZW5hYmxlZC4KICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmVuYWJsZWQgfHwgdGhpcy5lbmFibGVkKSB7CiAgICAgICAgICAgICAgICAgICAgLy9FbmFibGUgdGhpcyBtb2R1bGUgYW5kIGRlcGVuZGVuY2llcy4KICAgICAgICAgICAgICAgICAgICAvL1dpbGwgY2FsbCB0aGlzLmNoZWNrKCkKICAgICAgICAgICAgICAgICAgICB0aGlzLmVuYWJsZSgpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmNoZWNrKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBkZWZpbmVEZXA6IGZ1bmN0aW9uIChpLCBkZXBFeHBvcnRzKSB7CiAgICAgICAgICAgICAgICAvL0JlY2F1c2Ugb2YgY3ljbGVzLCBkZWZpbmVkIGNhbGxiYWNrIGZvciBhIGdpdmVuCiAgICAgICAgICAgICAgICAvL2V4cG9ydCBjYW4gYmUgY2FsbGVkIG1vcmUgdGhhbiBvbmNlLgogICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRlcE1hdGNoZWRbaV0pIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmRlcE1hdGNoZWRbaV0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIHRoaXMuZGVwQ291bnQgLT0gMTsKICAgICAgICAgICAgICAgICAgICB0aGlzLmRlcEV4cG9ydHNbaV0gPSBkZXBFeHBvcnRzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZmV0Y2g6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIGlmICh0aGlzLmZldGNoZWQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0aGlzLmZldGNoZWQgPSB0cnVlOwoKICAgICAgICAgICAgICAgIGNvbnRleHQuc3RhcnRUaW1lID0gKG5ldyBEYXRlKCkpLmdldFRpbWUoKTsKCiAgICAgICAgICAgICAgICB2YXIgbWFwID0gdGhpcy5tYXA7CgogICAgICAgICAgICAgICAgLy9JZiB0aGUgbWFuYWdlciBpcyBmb3IgYSBwbHVnaW4gbWFuYWdlZCByZXNvdXJjZSwKICAgICAgICAgICAgICAgIC8vYXNrIHRoZSBwbHVnaW4gdG8gbG9hZCBpdCBub3cuCiAgICAgICAgICAgICAgICBpZiAodGhpcy5zaGltKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5tYWtlUmVxdWlyZSh0aGlzLm1hcCwgewogICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVCdWlsZENhbGxiYWNrOiB0cnVlCiAgICAgICAgICAgICAgICAgICAgfSkodGhpcy5zaGltLmRlcHMgfHwgW10sIGJpbmQodGhpcywgZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwLnByZWZpeCA/IHRoaXMuY2FsbFBsdWdpbigpIDogdGhpcy5sb2FkKCk7CiAgICAgICAgICAgICAgICAgICAgfSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvL1JlZ3VsYXIgZGVwZW5kZW5jeS4KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWFwLnByZWZpeCA/IHRoaXMuY2FsbFBsdWdpbigpIDogdGhpcy5sb2FkKCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICBsb2FkOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgdXJsID0gdGhpcy5tYXAudXJsOwoKICAgICAgICAgICAgICAgIC8vUmVndWxhciBkZXBlbmRlbmN5LgogICAgICAgICAgICAgICAgaWYgKCF1cmxGZXRjaGVkW3VybF0pIHsKICAgICAgICAgICAgICAgICAgICB1cmxGZXRjaGVkW3VybF0gPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIGNvbnRleHQubG9hZCh0aGlzLm1hcC5pZCwgdXJsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDaGVja3MgaWYgdGhlIG1vZHVsZSBpcyByZWFkeSB0byBkZWZpbmUgaXRzZWxmLCBhbmQgaWYgc28sCiAgICAgICAgICAgICAqIGRlZmluZSBpdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNoZWNrOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZW5hYmxlZCB8fCB0aGlzLmVuYWJsaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHZhciBlcnIsIGNqc01vZHVsZSwKICAgICAgICAgICAgICAgICAgICBpZCA9IHRoaXMubWFwLmlkLAogICAgICAgICAgICAgICAgICAgIGRlcEV4cG9ydHMgPSB0aGlzLmRlcEV4cG9ydHMsCiAgICAgICAgICAgICAgICAgICAgZXhwb3J0cyA9IHRoaXMuZXhwb3J0cywKICAgICAgICAgICAgICAgICAgICBmYWN0b3J5ID0gdGhpcy5mYWN0b3J5OwoKICAgICAgICAgICAgICAgIGlmICghdGhpcy5pbml0ZWQpIHsKICAgICAgICAgICAgICAgICAgICAvLyBPbmx5IGZldGNoIGlmIG5vdCBhbHJlYWR5IGluIHRoZSBkZWZRdWV1ZS4KICAgICAgICAgICAgICAgICAgICBpZiAoIWhhc1Byb3AoY29udGV4dC5kZWZRdWV1ZU1hcCwgaWQpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmV0Y2goKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgdGhpcy5lcnJvcik7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmRlZmluaW5nKSB7CiAgICAgICAgICAgICAgICAgICAgLy9UaGUgZmFjdG9yeSBjb3VsZCB0cmlnZ2VyIGFub3RoZXIgcmVxdWlyZSBjYWxsCiAgICAgICAgICAgICAgICAgICAgLy90aGF0IHdvdWxkIHJlc3VsdCBpbiBjaGVja2luZyB0aGlzIG1vZHVsZSB0bwogICAgICAgICAgICAgICAgICAgIC8vZGVmaW5lIGl0c2VsZiBhZ2Fpbi4gSWYgYWxyZWFkeSBpbiB0aGUgcHJvY2VzcwogICAgICAgICAgICAgICAgICAgIC8vb2YgZG9pbmcgdGhhdCwgc2tpcCB0aGlzIHdvcmsuCiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWZpbmluZyA9IHRydWU7CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlcENvdW50IDwgMSAmJiAhdGhpcy5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Z1bmN0aW9uKGZhY3RvcnkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMgPSBjb250ZXh0LmV4ZWNDYihpZCwgZmFjdG9yeSwgZGVwRXhwb3J0cywgZXhwb3J0cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyID0gZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGYXZvciByZXR1cm4gdmFsdWUgb3ZlciBleHBvcnRzLiBJZiBub2RlL2NqcyBpbiBwbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhlbiB3aWxsIG5vdCBoYXZlIGEgcmV0dXJuIHZhbHVlIGFueXdheS4gRmF2b3IKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1vZHVsZS5leHBvcnRzIGFzc2lnbm1lbnQgb3ZlciBleHBvcnRzIG9iamVjdC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLm1hcC5pc0RlZmluZSAmJiBleHBvcnRzID09PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUgPSB0aGlzLm1vZHVsZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2pzTW9kdWxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMgPSBjanNNb2R1bGUuZXhwb3J0czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudXNpbmdFeHBvcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZXhwb3J0cyBhbHJlYWR5IHNldCB0aGUgZGVmaW5lZCB2YWx1ZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3J0cyA9IHRoaXMuZXhwb3J0czsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGFuIGVycm9yIGxpc3RlbmVyLCBmYXZvciBwYXNzaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdG8gdGhhdCBpbnN0ZWFkIG9mIHRocm93aW5nIGFuIGVycm9yLiBIb3dldmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9ubHkgZG8gaXQgZm9yIGRlZmluZSgpJ2QgIG1vZHVsZXMuIHJlcXVpcmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlcnJiYWNrcyBzaG91bGQgbm90IGJlIGNhbGxlZCBmb3IgZmFpbHVyZXMgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGVpciBjYWxsYmFja3MgKCM2OTkpLiBIb3dldmVyIGlmIGEgZ2xvYmFsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb25FcnJvciBpcyBzZXQsIHVzZSB0aGF0LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodGhpcy5ldmVudHMuZXJyb3IgJiYgdGhpcy5tYXAuaXNEZWZpbmUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5vbkVycm9yICE9PSBkZWZhdWx0T25FcnJvcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIucmVxdWlyZU1hcCA9IHRoaXMubWFwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIucmVxdWlyZU1vZHVsZXMgPSB0aGlzLm1hcC5pc0RlZmluZSA/IFt0aGlzLm1hcC5pZF0gOiBudWxsOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIucmVxdWlyZVR5cGUgPSB0aGlzLm1hcC5pc0RlZmluZSA/ICdkZWZpbmUnIDogJ3JlcXVpcmUnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb25FcnJvcigodGhpcy5lcnJvciA9IGVycikpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExvZyB0aGUgZXJyb3IgZm9yIGRlYnVnZ2luZy4gSWYgcHJvbWlzZXMgY291bGQgYmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdXNlZCwgdGhpcyB3b3VsZCBiZSBkaWZmZXJlbnQsIGJ1dCBtYWtpbmcgZG8uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEbyBub3Qgd2FudCB0byBjb21wbGV0ZWx5IGxvc2UgdGhlIGVycm9yLiBXaGlsZSB0aGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpbGwgbWVzcyB1cCBwcm9jZXNzaW5nIGFuZCBsZWFkIHRvIHNpbWlsYXIgcmVzdWx0cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcyBidWcgMTQ0MCwgaXQgYXQgbGVhc3Qgc3VyZmFjZXMgdGhlIGVycm9yLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXEub25FcnJvcihlcnIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vSnVzdCBhIGxpdGVyYWwgdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9ydHMgPSBmYWN0b3J5OwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmV4cG9ydHMgPSBleHBvcnRzOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWFwLmlzRGVmaW5lICYmICF0aGlzLmlnbm9yZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lZFtpZF0gPSBleHBvcnRzOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXEub25SZXNvdXJjZUxvYWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzTG9hZE1hcHMgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKHRoaXMuZGVwTWFwcywgZnVuY3Rpb24gKGRlcE1hcCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNMb2FkTWFwcy5wdXNoKGRlcE1hcC5ub3JtYWxpemVkTWFwIHx8IGRlcE1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxLm9uUmVzb3VyY2VMb2FkKGNvbnRleHQsIHRoaXMubWFwLCByZXNMb2FkTWFwcyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vQ2xlYW4gdXAKICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW5SZWdpc3RyeShpZCk7CgogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmluZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy9GaW5pc2hlZCB0aGUgZGVmaW5lIHN0YWdlLiBBbGxvdyBjYWxsaW5nIGNoZWNrIGFnYWluCiAgICAgICAgICAgICAgICAgICAgLy90byBhbGxvdyBkZWZpbmUgbm90aWZpY2F0aW9ucyBiZWxvdyBpbiB0aGUgY2FzZSBvZiBhCiAgICAgICAgICAgICAgICAgICAgLy9jeWNsZS4KICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmluaW5nID0gZmFsc2U7CgogICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlZmluZWQgJiYgIXRoaXMuZGVmaW5lRW1pdHRlZCkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmluZUVtaXR0ZWQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2RlZmluZWQnLCB0aGlzLmV4cG9ydHMpOwogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmluZUVtaXRDb21wbGV0ZSA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGNhbGxQbHVnaW46IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLm1hcCwKICAgICAgICAgICAgICAgICAgICBpZCA9IG1hcC5pZCwKICAgICAgICAgICAgICAgICAgICAvL01hcCBhbHJlYWR5IG5vcm1hbGl6ZWQgdGhlIHByZWZpeC4KICAgICAgICAgICAgICAgICAgICBwbHVnaW5NYXAgPSBtYWtlTW9kdWxlTWFwKG1hcC5wcmVmaXgpOwoKICAgICAgICAgICAgICAgIC8vTWFyayB0aGlzIGFzIGEgZGVwZW5kZW5jeSBmb3IgdGhpcyBwbHVnaW4sIHNvIGl0CiAgICAgICAgICAgICAgICAvL2NhbiBiZSB0cmFjZWQgZm9yIGN5Y2xlcy4KICAgICAgICAgICAgICAgIHRoaXMuZGVwTWFwcy5wdXNoKHBsdWdpbk1hcCk7CgogICAgICAgICAgICAgICAgb24ocGx1Z2luTWFwLCAnZGVmaW5lZCcsIGJpbmQodGhpcywgZnVuY3Rpb24gKHBsdWdpbikgewogICAgICAgICAgICAgICAgICAgIHZhciBsb2FkLCBub3JtYWxpemVkTWFwLCBub3JtYWxpemVkTW9kLAogICAgICAgICAgICAgICAgICAgICAgICBidW5kbGVJZCA9IGdldE93bihidW5kbGVzTWFwLCB0aGlzLm1hcC5pZCksCiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSB0aGlzLm1hcC5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROYW1lID0gdGhpcy5tYXAucGFyZW50TWFwID8gdGhpcy5tYXAucGFyZW50TWFwLm5hbWUgOiBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFJlcXVpcmUgPSBjb250ZXh0Lm1ha2VSZXF1aXJlKG1hcC5wYXJlbnRNYXAsIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZUJ1aWxkQ2FsbGJhY2s6IHRydWUKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgICAgIC8vSWYgY3VycmVudCBtYXAgaXMgbm90IG5vcm1hbGl6ZWQsIHdhaXQgZm9yIHRoYXQKICAgICAgICAgICAgICAgICAgICAvL25vcm1hbGl6ZWQgbmFtZSB0byBsb2FkIGluc3RlYWQgb2YgY29udGludWluZy4KICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXAudW5ub3JtYWxpemVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vTm9ybWFsaXplIHRoZSBJRCBpZiB0aGUgcGx1Z2luIGFsbG93cyBpdC4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5ub3JtYWxpemUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSBwbHVnaW4ubm9ybWFsaXplKG5hbWUsIGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZShuYW1lLCBwYXJlbnROYW1lLCB0cnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pIHx8ICcnOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvL3ByZWZpeCBhbmQgbmFtZSBzaG91bGQgYWxyZWFkeSBiZSBub3JtYWxpemVkLCBubyBuZWVkCiAgICAgICAgICAgICAgICAgICAgICAgIC8vZm9yIGFwcGx5aW5nIG1hcCBjb25maWcgYWdhaW4gZWl0aGVyLgogICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTWFwID0gbWFrZU1vZHVsZU1hcChtYXAucHJlZml4ICsgJyEnICsgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXAucGFyZW50TWFwKTsKICAgICAgICAgICAgICAgICAgICAgICAgb24obm9ybWFsaXplZE1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkZWZpbmVkJywgYmluZCh0aGlzLCBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcC5ub3JtYWxpemVkTWFwID0gbm9ybWFsaXplZE1hcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXQoW10sIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9LCBudWxsLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlnbm9yZTogdHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZE1vZCA9IGdldE93bihyZWdpc3RyeSwgbm9ybWFsaXplZE1hcC5pZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkTW9kKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01hcmsgdGhpcyBhcyBhIGRlcGVuZGVuY3kgZm9yIHRoaXMgcGx1Z2luLCBzbyBpdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9jYW4gYmUgdHJhY2VkIGZvciBjeWNsZXMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlcE1hcHMucHVzaChub3JtYWxpemVkTWFwKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5ldmVudHMuZXJyb3IpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTW9kLm9uKCdlcnJvcicsIGJpbmQodGhpcywgZnVuY3Rpb24gKGVycikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkTW9kLmVuYWJsZSgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL0lmIGEgcGF0aHMgY29uZmlnLCB0aGVuIGp1c3QgbG9hZCB0aGF0IGZpbGUgaW5zdGVhZCB0bwogICAgICAgICAgICAgICAgICAgIC8vcmVzb2x2ZSB0aGUgcGx1Z2luLCBhcyBpdCBpcyBidWlsdCBpbnRvIHRoYXQgcGF0aHMgbGF5ZXIuCiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1bmRsZUlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWFwLnVybCA9IGNvbnRleHQubmFtZVRvVXJsKGJ1bmRsZUlkKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGxvYWQgPSBiaW5kKHRoaXMsIGZ1bmN0aW9uICh2YWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluaXQoW10sIGZ1bmN0aW9uICgpIHsgcmV0dXJuIHZhbHVlOyB9LCBudWxsLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICBsb2FkLmVycm9yID0gYmluZCh0aGlzLCBmdW5jdGlvbiAoZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5pdGVkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lcnJvciA9IGVycjsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyLnJlcXVpcmVNb2R1bGVzID0gW2lkXTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vUmVtb3ZlIHRlbXAgdW5ub3JtYWxpemVkIG1vZHVsZXMgZm9yIHRoaXMgbW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAvL3NpbmNlIHRoZXkgd2lsbCBuZXZlciBiZSByZXNvbHZlZCBvdGhlcndpc2Ugbm93LgogICAgICAgICAgICAgICAgICAgICAgICBlYWNoUHJvcChyZWdpc3RyeSwgZnVuY3Rpb24gKG1vZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZC5tYXAuaWQuaW5kZXhPZihpZCArICdfdW5ub3JtYWxpemVkJykgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhblJlZ2lzdHJ5KG1vZC5tYXAuaWQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIG9uRXJyb3IoZXJyKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLy9BbGxvdyBwbHVnaW5zIHRvIGxvYWQgb3RoZXIgY29kZSB3aXRob3V0IGhhdmluZyB0byBrbm93IHRoZQogICAgICAgICAgICAgICAgICAgIC8vY29udGV4dCBvciBob3cgdG8gJ2NvbXBsZXRlJyB0aGUgbG9hZC4KICAgICAgICAgICAgICAgICAgICBsb2FkLmZyb21UZXh0ID0gYmluZCh0aGlzLCBmdW5jdGlvbiAodGV4dCwgdGV4dEFsdCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKmpzbGludCBldmlsOiB0cnVlICovCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtb2R1bGVOYW1lID0gbWFwLm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVNYXAgPSBtYWtlTW9kdWxlTWFwKG1vZHVsZU5hbWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzSW50ZXJhY3RpdmUgPSB1c2VJbnRlcmFjdGl2ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vQXMgb2YgMi4xLjAsIHN1cHBvcnQganVzdCBwYXNzaW5nIHRoZSB0ZXh0LCB0byByZWluZm9yY2UKICAgICAgICAgICAgICAgICAgICAgICAgLy9mcm9tVGV4dCBvbmx5IGJlaW5nIGNhbGxlZCBvbmNlIHBlciByZXNvdXJjZS4gU3RpbGwKICAgICAgICAgICAgICAgICAgICAgICAgLy9zdXBwb3J0IG9sZCBzdHlsZSBvZiBwYXNzaW5nIG1vZHVsZU5hbWUgYnV0IGRpc2NhcmQKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGF0IG1vZHVsZU5hbWUgaW4gZmF2b3Igb2YgdGhlIGludGVybmFsIHJlZi4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRleHRBbHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSB0ZXh0QWx0OwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvL1R1cm4gb2ZmIGludGVyYWN0aXZlIHNjcmlwdCBtYXRjaGluZyBmb3IgSUUgZm9yIGFueSBkZWZpbmUKICAgICAgICAgICAgICAgICAgICAgICAgLy9jYWxscyBpbiB0aGUgdGV4dCwgdGhlbiB0dXJuIGl0IGJhY2sgb24gYXQgdGhlIGVuZC4KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc0ludGVyYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VJbnRlcmFjdGl2ZSA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvL1ByaW1lIHRoZSBzeXN0ZW0gYnkgY3JlYXRpbmcgYSBtb2R1bGUgaW5zdGFuY2UgZm9yCiAgICAgICAgICAgICAgICAgICAgICAgIC8vaXQuCiAgICAgICAgICAgICAgICAgICAgICAgIGdldE1vZHVsZShtb2R1bGVNYXApOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9UcmFuc2ZlciBhbnkgY29uZmlnIHRvIHRoaXMgb3RoZXIgbW9kdWxlLgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzUHJvcChjb25maWcuY29uZmlnLCBpZCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5jb25maWdbbW9kdWxlTmFtZV0gPSBjb25maWcuY29uZmlnW2lkXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcS5leGVjKHRleHQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gb25FcnJvcihtYWtlRXJyb3IoJ2Zyb210ZXh0ZXZhbCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmcm9tVGV4dCBldmFsIGZvciAnICsgaWQgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgZmFpbGVkOiAnICsgZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2lkXSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzSW50ZXJhY3RpdmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZUludGVyYWN0aXZlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy9NYXJrIHRoaXMgYXMgYSBkZXBlbmRlbmN5IGZvciB0aGUgcGx1Z2luCiAgICAgICAgICAgICAgICAgICAgICAgIC8vcmVzb3VyY2UKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXBNYXBzLnB1c2gobW9kdWxlTWFwKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vU3VwcG9ydCBhbm9ueW1vdXMgbW9kdWxlcy4KICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5jb21wbGV0ZUxvYWQobW9kdWxlTmFtZSk7CgogICAgICAgICAgICAgICAgICAgICAgICAvL0JpbmQgdGhlIHZhbHVlIG9mIHRoYXQgbW9kdWxlIHRvIHRoZSB2YWx1ZSBmb3IgdGhpcwogICAgICAgICAgICAgICAgICAgICAgICAvL3Jlc291cmNlIElELgogICAgICAgICAgICAgICAgICAgICAgICBsb2NhbFJlcXVpcmUoW21vZHVsZU5hbWVdLCBsb2FkKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgLy9Vc2UgcGFyZW50TmFtZSBoZXJlIHNpbmNlIHRoZSBwbHVnaW4ncyBuYW1lIGlzIG5vdCByZWxpYWJsZSwKICAgICAgICAgICAgICAgICAgICAvL2NvdWxkIGJlIHNvbWUgd2VpcmQgc3RyaW5nIHdpdGggbm8gcGF0aCB0aGF0IGFjdHVhbGx5IHdhbnRzIHRvCiAgICAgICAgICAgICAgICAgICAgLy9yZWZlcmVuY2UgdGhlIHBhcmVudE5hbWUncyBwYXRoLgogICAgICAgICAgICAgICAgICAgIHBsdWdpbi5sb2FkKG1hcC5uYW1lLCBsb2NhbFJlcXVpcmUsIGxvYWQsIGNvbmZpZyk7CiAgICAgICAgICAgICAgICB9KSk7CgogICAgICAgICAgICAgICAgY29udGV4dC5lbmFibGUocGx1Z2luTWFwLCB0aGlzKTsKICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luTWFwc1twbHVnaW5NYXAuaWRdID0gcGx1Z2luTWFwOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgZW5hYmxlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICBlbmFibGVkUmVnaXN0cnlbdGhpcy5tYXAuaWRdID0gdGhpczsKICAgICAgICAgICAgICAgIHRoaXMuZW5hYmxlZCA9IHRydWU7CgogICAgICAgICAgICAgICAgLy9TZXQgZmxhZyBtZW50aW9uaW5nIHRoYXQgdGhlIG1vZHVsZSBpcyBlbmFibGluZywKICAgICAgICAgICAgICAgIC8vc28gdGhhdCBpbW1lZGlhdGUgY2FsbHMgdG8gdGhlIGRlZmluZWQgY2FsbGJhY2tzCiAgICAgICAgICAgICAgICAvL2ZvciBkZXBlbmRlbmNpZXMgZG8gbm90IHRyaWdnZXIgaW5hZHZlcnRlbnQgbG9hZAogICAgICAgICAgICAgICAgLy93aXRoIHRoZSBkZXBDb3VudCBzdGlsbCBiZWluZyB6ZXJvLgogICAgICAgICAgICAgICAgdGhpcy5lbmFibGluZyA9IHRydWU7CgogICAgICAgICAgICAgICAgLy9FbmFibGUgZWFjaCBkZXBlbmRlbmN5CiAgICAgICAgICAgICAgICBlYWNoKHRoaXMuZGVwTWFwcywgYmluZCh0aGlzLCBmdW5jdGlvbiAoZGVwTWFwLCBpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGlkLCBtb2QsIGhhbmRsZXI7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZGVwTWFwID09PSAnc3RyaW5nJykgewogICAgICAgICAgICAgICAgICAgICAgICAvL0RlcGVuZGVuY3kgbmVlZHMgdG8gYmUgY29udmVydGVkIHRvIGEgZGVwTWFwCiAgICAgICAgICAgICAgICAgICAgICAgIC8vYW5kIHdpcmVkIHVwIHRvIHRoaXMgbW9kdWxlLgogICAgICAgICAgICAgICAgICAgICAgICBkZXBNYXAgPSBtYWtlTW9kdWxlTWFwKGRlcE1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodGhpcy5tYXAuaXNEZWZpbmUgPyB0aGlzLm1hcCA6IHRoaXMubWFwLnBhcmVudE1hcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXRoaXMuc2tpcE1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVwTWFwc1tpXSA9IGRlcE1hcDsKCiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXIgPSBnZXRPd24oaGFuZGxlcnMsIGRlcE1hcC5pZCk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFuZGxlcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXBFeHBvcnRzW2ldID0gaGFuZGxlcih0aGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXBDb3VudCArPSAxOwoKICAgICAgICAgICAgICAgICAgICAgICAgb24oZGVwTWFwLCAnZGVmaW5lZCcsIGJpbmQodGhpcywgZnVuY3Rpb24gKGRlcEV4cG9ydHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnVuZGVmZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlZmluZURlcChpLCBkZXBFeHBvcnRzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2soKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZXJyYmFjaykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgb24oZGVwTWFwLCAnZXJyb3InLCBiaW5kKHRoaXMsIHRoaXMuZXJyYmFjaykpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZXZlbnRzLmVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBObyBkaXJlY3QgZXJyYmFjayBvbiB0aGlzIG1vZHVsZSwgYnV0IHNvbWV0aGluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWxzZSBpcyBsaXN0ZW5pbmcgZm9yIGVycm9ycywgc28gYmUgc3VyZSB0bwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJvcGFnYXRlIHRoZSBlcnJvciBjb3JyZWN0bHkuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbihkZXBNYXAsICdlcnJvcicsIGJpbmQodGhpcywgZnVuY3Rpb24oZXJyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlkID0gZGVwTWFwLmlkOwogICAgICAgICAgICAgICAgICAgIG1vZCA9IHJlZ2lzdHJ5W2lkXTsKCiAgICAgICAgICAgICAgICAgICAgLy9Ta2lwIHNwZWNpYWwgbW9kdWxlcyBsaWtlICdyZXF1aXJlJywgJ2V4cG9ydHMnLCAnbW9kdWxlJwogICAgICAgICAgICAgICAgICAgIC8vQWxzbywgZG9uJ3QgY2FsbCBlbmFibGUgaWYgaXQgaXMgYWxyZWFkeSBlbmFibGVkLAogICAgICAgICAgICAgICAgICAgIC8vaW1wb3J0YW50IGluIGNpcmN1bGFyIGRlcGVuZGVuY3kgY2FzZXMuCiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNQcm9wKGhhbmRsZXJzLCBpZCkgJiYgbW9kICYmICFtb2QuZW5hYmxlZCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVuYWJsZShkZXBNYXAsIHRoaXMpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pKTsKCiAgICAgICAgICAgICAgICAvL0VuYWJsZSBlYWNoIHBsdWdpbiB0aGF0IGlzIHVzZWQgaW4KICAgICAgICAgICAgICAgIC8vYSBkZXBlbmRlbmN5CiAgICAgICAgICAgICAgICBlYWNoUHJvcCh0aGlzLnBsdWdpbk1hcHMsIGJpbmQodGhpcywgZnVuY3Rpb24gKHBsdWdpbk1hcCkgewogICAgICAgICAgICAgICAgICAgIHZhciBtb2QgPSBnZXRPd24ocmVnaXN0cnksIHBsdWdpbk1hcC5pZCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKG1vZCAmJiAhbW9kLmVuYWJsZWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5lbmFibGUocGx1Z2luTWFwLCB0aGlzKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9KSk7CgogICAgICAgICAgICAgICAgdGhpcy5lbmFibGluZyA9IGZhbHNlOwoKICAgICAgICAgICAgICAgIHRoaXMuY2hlY2soKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG9uOiBmdW5jdGlvbiAobmFtZSwgY2IpIHsKICAgICAgICAgICAgICAgIHZhciBjYnMgPSB0aGlzLmV2ZW50c1tuYW1lXTsKICAgICAgICAgICAgICAgIGlmICghY2JzKSB7CiAgICAgICAgICAgICAgICAgICAgY2JzID0gdGhpcy5ldmVudHNbbmFtZV0gPSBbXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNicy5wdXNoKGNiKTsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIGVtaXQ6IGZ1bmN0aW9uIChuYW1lLCBldnQpIHsKICAgICAgICAgICAgICAgIGVhY2godGhpcy5ldmVudHNbbmFtZV0sIGZ1bmN0aW9uIChjYikgewogICAgICAgICAgICAgICAgICAgIGNiKGV2dCk7CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSAnZXJyb3InKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Ob3cgdGhhdCB0aGUgZXJyb3IgaGFuZGxlciB3YXMgdHJpZ2dlcmVkLCByZW1vdmUKICAgICAgICAgICAgICAgICAgICAvL3RoZSBsaXN0ZW5lcnMsIHNpbmNlIHRoaXMgYnJva2VuIE1vZHVsZSBpbnN0YW5jZQogICAgICAgICAgICAgICAgICAgIC8vY2FuIHN0YXkgYXJvdW5kIGZvciBhIHdoaWxlIGluIHRoZSByZWdpc3RyeS4KICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5ldmVudHNbbmFtZV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBmdW5jdGlvbiBjYWxsR2V0TW9kdWxlKGFyZ3MpIHsKICAgICAgICAgICAgLy9Ta2lwIG1vZHVsZXMgYWxyZWFkeSBkZWZpbmVkLgogICAgICAgICAgICBpZiAoIWhhc1Byb3AoZGVmaW5lZCwgYXJnc1swXSkpIHsKICAgICAgICAgICAgICAgIGdldE1vZHVsZShtYWtlTW9kdWxlTWFwKGFyZ3NbMF0sIG51bGwsIHRydWUpKS5pbml0KGFyZ3NbMV0sIGFyZ3NbMl0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihub2RlLCBmdW5jLCBuYW1lLCBpZU5hbWUpIHsKICAgICAgICAgICAgLy9GYXZvciBkZXRhY2hFdmVudCBiZWNhdXNlIG9mIElFOQogICAgICAgICAgICAvL2lzc3VlLCBzZWUgYXR0YWNoRXZlbnQvYWRkRXZlbnRMaXN0ZW5lciBjb21tZW50IGVsc2V3aGVyZQogICAgICAgICAgICAvL2luIHRoaXMgZmlsZS4KICAgICAgICAgICAgaWYgKG5vZGUuZGV0YWNoRXZlbnQgJiYgIWlzT3BlcmEpIHsKICAgICAgICAgICAgICAgIC8vUHJvYmFibHkgSUUuIElmIG5vdCBpdCB3aWxsIHRocm93IGFuIGVycm9yLCB3aGljaCB3aWxsIGJlCiAgICAgICAgICAgICAgICAvL3VzZWZ1bCB0byBrbm93LgogICAgICAgICAgICAgICAgaWYgKGllTmFtZSkgewogICAgICAgICAgICAgICAgICAgIG5vZGUuZGV0YWNoRXZlbnQoaWVOYW1lLCBmdW5jKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBmdW5jLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIEdpdmVuIGFuIGV2ZW50IGZyb20gYSBzY3JpcHQgbm9kZSwgZ2V0IHRoZSByZXF1aXJlanMgaW5mbyBmcm9tIGl0LAogICAgICAgICAqIGFuZCB0aGVuIHJlbW92ZXMgdGhlIGV2ZW50IGxpc3RlbmVycyBvbiB0aGUgbm9kZS4KICAgICAgICAgKiBAcGFyYW0ge0V2ZW50fSBldnQKICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fQogICAgICAgICAqLwogICAgICAgIGZ1bmN0aW9uIGdldFNjcmlwdERhdGEoZXZ0KSB7CiAgICAgICAgICAgIC8vVXNpbmcgY3VycmVudFRhcmdldCBpbnN0ZWFkIG9mIHRhcmdldCBmb3IgRmlyZWZveCAyLjAncyBzYWtlLiBOb3QKICAgICAgICAgICAgLy9hbGwgb2xkIGJyb3dzZXJzIHdpbGwgYmUgc3VwcG9ydGVkLCBidXQgdGhpcyBvbmUgd2FzIGVhc3kgZW5vdWdoCiAgICAgICAgICAgIC8vdG8gc3VwcG9ydCBhbmQgc3RpbGwgbWFrZXMgc2Vuc2UuCiAgICAgICAgICAgIHZhciBub2RlID0gZXZ0LmN1cnJlbnRUYXJnZXQgfHwgZXZ0LnNyY0VsZW1lbnQ7CgogICAgICAgICAgICAvL1JlbW92ZSB0aGUgbGlzdGVuZXJzIG9uY2UgaGVyZS4KICAgICAgICAgICAgcmVtb3ZlTGlzdGVuZXIobm9kZSwgY29udGV4dC5vblNjcmlwdExvYWQsICdsb2FkJywgJ29ucmVhZHlzdGF0ZWNoYW5nZScpOwogICAgICAgICAgICByZW1vdmVMaXN0ZW5lcihub2RlLCBjb250ZXh0Lm9uU2NyaXB0RXJyb3IsICdlcnJvcicpOwoKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAgIG5vZGU6IG5vZGUsCiAgICAgICAgICAgICAgICBpZDogbm9kZSAmJiBub2RlLmdldEF0dHJpYnV0ZSgnZGF0YS1yZXF1aXJlbW9kdWxlJykKICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIGZ1bmN0aW9uIGludGFrZURlZmluZXMoKSB7CiAgICAgICAgICAgIHZhciBhcmdzOwoKICAgICAgICAgICAgLy9BbnkgZGVmaW5lZCBtb2R1bGVzIGluIHRoZSBnbG9iYWwgcXVldWUsIGludGFrZSB0aGVtIG5vdy4KICAgICAgICAgICAgdGFrZUdsb2JhbFF1ZXVlKCk7CgogICAgICAgICAgICAvL01ha2Ugc3VyZSBhbnkgcmVtYWluaW5nIGRlZlF1ZXVlIGl0ZW1zIGdldCBwcm9wZXJseSBwcm9jZXNzZWQuCiAgICAgICAgICAgIHdoaWxlIChkZWZRdWV1ZS5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGFyZ3MgPSBkZWZRdWV1ZS5zaGlmdCgpOwogICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb25FcnJvcihtYWtlRXJyb3IoJ21pc21hdGNoJywgJ01pc21hdGNoZWQgYW5vbnltb3VzIGRlZmluZSgpIG1vZHVsZTogJyArCiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbYXJncy5sZW5ndGggLSAxXSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvL2FyZ3MgYXJlIGlkLCBkZXBzLCBmYWN0b3J5LiBTaG91bGQgYmUgbm9ybWFsaXplZCBieSB0aGUKICAgICAgICAgICAgICAgICAgICAvL2RlZmluZSgpIGZ1bmN0aW9uLgogICAgICAgICAgICAgICAgICAgIGNhbGxHZXRNb2R1bGUoYXJncyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGV4dC5kZWZRdWV1ZU1hcCA9IHt9OwogICAgICAgIH0KCiAgICAgICAgY29udGV4dCA9IHsKICAgICAgICAgICAgY29uZmlnOiBjb25maWcsCiAgICAgICAgICAgIGNvbnRleHROYW1lOiBjb250ZXh0TmFtZSwKICAgICAgICAgICAgcmVnaXN0cnk6IHJlZ2lzdHJ5LAogICAgICAgICAgICBkZWZpbmVkOiBkZWZpbmVkLAogICAgICAgICAgICB1cmxGZXRjaGVkOiB1cmxGZXRjaGVkLAogICAgICAgICAgICBkZWZRdWV1ZTogZGVmUXVldWUsCiAgICAgICAgICAgIGRlZlF1ZXVlTWFwOiB7fSwKICAgICAgICAgICAgTW9kdWxlOiBNb2R1bGUsCiAgICAgICAgICAgIG1ha2VNb2R1bGVNYXA6IG1ha2VNb2R1bGVNYXAsCiAgICAgICAgICAgIG5leHRUaWNrOiByZXEubmV4dFRpY2ssCiAgICAgICAgICAgIG9uRXJyb3I6IG9uRXJyb3IsCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2V0IGEgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNvbnRleHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgY29uZmlnIG9iamVjdCB0byBpbnRlZ3JhdGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjb25maWd1cmU6IGZ1bmN0aW9uIChjZmcpIHsKICAgICAgICAgICAgICAgIC8vTWFrZSBzdXJlIHRoZSBiYXNlVXJsIGVuZHMgaW4gYSBzbGFzaC4KICAgICAgICAgICAgICAgIGlmIChjZmcuYmFzZVVybCkgewogICAgICAgICAgICAgICAgICAgIGlmIChjZmcuYmFzZVVybC5jaGFyQXQoY2ZnLmJhc2VVcmwubGVuZ3RoIC0gMSkgIT09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICBjZmcuYmFzZVVybCArPSAnLyc7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vU2F2ZSBvZmYgdGhlIHBhdGhzIHNpbmNlIHRoZXkgcmVxdWlyZSBzcGVjaWFsIHByb2Nlc3NpbmcsCiAgICAgICAgICAgICAgICAvL3RoZXkgYXJlIGFkZGl0aXZlLgogICAgICAgICAgICAgICAgdmFyIHNoaW0gPSBjb25maWcuc2hpbSwKICAgICAgICAgICAgICAgICAgICBvYmpzID0gewogICAgICAgICAgICAgICAgICAgICAgICBwYXRoczogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgYnVuZGxlczogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBtYXA6IHRydWUKICAgICAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIGVhY2hQcm9wKGNmZywgZnVuY3Rpb24gKHZhbHVlLCBwcm9wKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKG9ianNbcHJvcF0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjb25maWdbcHJvcF0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ1twcm9wXSA9IHt9OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIG1peGluKGNvbmZpZ1twcm9wXSwgdmFsdWUsIHRydWUsIHRydWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ1twcm9wXSA9IHZhbHVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgIC8vUmV2ZXJzZSBtYXAgdGhlIGJ1bmRsZXMKICAgICAgICAgICAgICAgIGlmIChjZmcuYnVuZGxlcykgewogICAgICAgICAgICAgICAgICAgIGVhY2hQcm9wKGNmZy5idW5kbGVzLCBmdW5jdGlvbiAodmFsdWUsIHByb3ApIHsKICAgICAgICAgICAgICAgICAgICAgICAgZWFjaCh2YWx1ZSwgZnVuY3Rpb24gKHYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ICE9PSBwcm9wKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVuZGxlc01hcFt2XSA9IHByb3A7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vTWVyZ2Ugc2hpbQogICAgICAgICAgICAgICAgaWYgKGNmZy5zaGltKSB7CiAgICAgICAgICAgICAgICAgICAgZWFjaFByb3AoY2ZnLnNoaW0sIGZ1bmN0aW9uICh2YWx1ZSwgaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9Ob3JtYWxpemUgdGhlIHN0cnVjdHVyZQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHM6IHZhbHVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgodmFsdWUuZXhwb3J0cyB8fCB2YWx1ZS5pbml0KSAmJiAhdmFsdWUuZXhwb3J0c0ZuKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5leHBvcnRzRm4gPSBjb250ZXh0Lm1ha2VTaGltRXhwb3J0cyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc2hpbVtpZF0gPSB2YWx1ZTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICBjb25maWcuc2hpbSA9IHNoaW07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy9BZGp1c3QgcGFja2FnZXMgaWYgbmVjZXNzYXJ5LgogICAgICAgICAgICAgICAgaWYgKGNmZy5wYWNrYWdlcykgewogICAgICAgICAgICAgICAgICAgIGVhY2goY2ZnLnBhY2thZ2VzLCBmdW5jdGlvbiAocGtnT2JqKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsb2NhdGlvbiwgbmFtZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHBrZ09iaiA9IHR5cGVvZiBwa2dPYmogPT09ICdzdHJpbmcnID8ge25hbWU6IHBrZ09ian0gOiBwa2dPYmo7CgogICAgICAgICAgICAgICAgICAgICAgICBuYW1lID0gcGtnT2JqLm5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uID0gcGtnT2JqLmxvY2F0aW9uOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobG9jYXRpb24pIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy5wYXRoc1tuYW1lXSA9IHBrZ09iai5sb2NhdGlvbjsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy9TYXZlIHBvaW50ZXIgdG8gbWFpbiBtb2R1bGUgSUQgZm9yIHBrZyBuYW1lLgogICAgICAgICAgICAgICAgICAgICAgICAvL1JlbW92ZSBsZWFkaW5nIGRvdCBpbiBtYWluLCBzbyBtYWluIHBhdGhzIGFyZSBub3JtYWxpemVkLAogICAgICAgICAgICAgICAgICAgICAgICAvL2FuZCByZW1vdmUgYW55IHRyYWlsaW5nIC5qcywgc2luY2UgZGlmZmVyZW50IHBhY2thZ2UKICAgICAgICAgICAgICAgICAgICAgICAgLy9lbnZzIGhhdmUgZGlmZmVyZW50IGNvbnZlbnRpb25zOiBzb21lIHVzZSBhIG1vZHVsZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAvL3NvbWUgdXNlIGEgZmlsZSBuYW1lLgogICAgICAgICAgICAgICAgICAgICAgICBjb25maWcucGtnc1tuYW1lXSA9IHBrZ09iai5uYW1lICsgJy8nICsgKHBrZ09iai5tYWluIHx8ICdtYWluJykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKGN1cnJEaXJSZWdFeHAsICcnKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoanNTdWZmaXhSZWdFeHAsICcnKTsKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0lmIHRoZXJlIGFyZSBhbnkgIndhaXRpbmcgdG8gZXhlY3V0ZSIgbW9kdWxlcyBpbiB0aGUgcmVnaXN0cnksCiAgICAgICAgICAgICAgICAvL3VwZGF0ZSB0aGUgbWFwcyBmb3IgdGhlbSwgc2luY2UgdGhlaXIgaW5mbywgbGlrZSBVUkxzIHRvIGxvYWQsCiAgICAgICAgICAgICAgICAvL21heSBoYXZlIGNoYW5nZWQuCiAgICAgICAgICAgICAgICBlYWNoUHJvcChyZWdpc3RyeSwgZnVuY3Rpb24gKG1vZCwgaWQpIHsKICAgICAgICAgICAgICAgICAgICAvL0lmIG1vZHVsZSBhbHJlYWR5IGhhcyBpbml0IGNhbGxlZCwgc2luY2UgaXQgaXMgdG9vCiAgICAgICAgICAgICAgICAgICAgLy9sYXRlIHRvIG1vZGlmeSB0aGVtLCBhbmQgaWdub3JlIHVubm9ybWFsaXplZCBvbmVzCiAgICAgICAgICAgICAgICAgICAgLy9zaW5jZSB0aGV5IGFyZSB0cmFuc2llbnQuCiAgICAgICAgICAgICAgICAgICAgaWYgKCFtb2QuaW5pdGVkICYmICFtb2QubWFwLnVubm9ybWFsaXplZCkgewogICAgICAgICAgICAgICAgICAgICAgICBtb2QubWFwID0gbWFrZU1vZHVsZU1hcChpZCwgbnVsbCwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgLy9JZiBhIGRlcHMgYXJyYXkgb3IgYSBjb25maWcgY2FsbGJhY2sgaXMgc3BlY2lmaWVkLCB0aGVuIGNhbGwKICAgICAgICAgICAgICAgIC8vcmVxdWlyZSB3aXRoIHRob3NlIGFyZ3MuIFRoaXMgaXMgdXNlZnVsIHdoZW4gcmVxdWlyZSBpcyBkZWZpbmVkIGFzIGEKICAgICAgICAgICAgICAgIC8vY29uZmlnIG9iamVjdCBiZWZvcmUgcmVxdWlyZS5qcyBpcyBsb2FkZWQuCiAgICAgICAgICAgICAgICBpZiAoY2ZnLmRlcHMgfHwgY2ZnLmNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5yZXF1aXJlKGNmZy5kZXBzIHx8IFtdLCBjZmcuY2FsbGJhY2spOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAoKICAgICAgICAgICAgbWFrZVNoaW1FeHBvcnRzOiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGZuKCkgewogICAgICAgICAgICAgICAgICAgIHZhciByZXQ7CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlLmluaXQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gdmFsdWUuaW5pdC5hcHBseShnbG9iYWwsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldHVybiByZXQgfHwgKHZhbHVlLmV4cG9ydHMgJiYgZ2V0R2xvYmFsKHZhbHVlLmV4cG9ydHMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBmbjsKICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIG1ha2VSZXF1aXJlOiBmdW5jdGlvbiAocmVsTWFwLCBvcHRpb25zKSB7CiAgICAgICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgICAgICAgICAgICAgICBmdW5jdGlvbiBsb2NhbFJlcXVpcmUoZGVwcywgY2FsbGJhY2ssIGVycmJhY2spIHsKICAgICAgICAgICAgICAgICAgICB2YXIgaWQsIG1hcCwgcmVxdWlyZU1vZDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlQnVpbGRDYWxsYmFjayAmJiBjYWxsYmFjayAmJiBpc0Z1bmN0aW9uKGNhbGxiYWNrKSkgewogICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5fX3JlcXVpcmVKc0J1aWxkID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZGVwcyA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oY2FsbGJhY2spKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0ludmFsaWQgY2FsbAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IobWFrZUVycm9yKCdyZXF1aXJlYXJncycsICdJbnZhbGlkIHJlcXVpcmUgY2FsbCcpLCBlcnJiYWNrKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLy9JZiByZXF1aXJlfGV4cG9ydHN8bW9kdWxlIGFyZSByZXF1ZXN0ZWQsIGdldCB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgLy92YWx1ZSBmb3IgdGhlbSBmcm9tIHRoZSBzcGVjaWFsIGhhbmRsZXJzLiBDYXZlYXQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC8vdGhpcyBvbmx5IHdvcmtzIHdoaWxlIG1vZHVsZSBpcyBiZWluZyBkZWZpbmVkLgogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVsTWFwICYmIGhhc1Byb3AoaGFuZGxlcnMsIGRlcHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlcnNbZGVwc10ocmVnaXN0cnlbcmVsTWFwLmlkXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vU3luY2hyb25vdXMgYWNjZXNzIHRvIG9uZSBtb2R1bGUuIElmIHJlcXVpcmUuZ2V0IGlzCiAgICAgICAgICAgICAgICAgICAgICAgIC8vYXZhaWxhYmxlIChhcyBpbiB0aGUgTm9kZSBhZGFwdGVyKSwgcHJlZmVyIHRoYXQuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXEuZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVxLmdldChjb250ZXh0LCBkZXBzLCByZWxNYXAsIGxvY2FsUmVxdWlyZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8vTm9ybWFsaXplIG1vZHVsZSBuYW1lLCBpZiBpdCBjb250YWlucyAuIG9yIC4uCiAgICAgICAgICAgICAgICAgICAgICAgIG1hcCA9IG1ha2VNb2R1bGVNYXAoZGVwcywgcmVsTWFwLCBmYWxzZSwgdHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gbWFwLmlkOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNQcm9wKGRlZmluZWQsIGlkKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IobWFrZUVycm9yKCdub3Rsb2FkZWQnLCAnTW9kdWxlIG5hbWUgIicgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyIgaGFzIG5vdCBiZWVuIGxvYWRlZCB5ZXQgZm9yIGNvbnRleHQ6ICcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dE5hbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlbE1hcCA/ICcnIDogJy4gVXNlIHJlcXVpcmUoW10pJykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmaW5lZFtpZF07CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvL0dyYWIgZGVmaW5lcyB3YWl0aW5nIGluIHRoZSBnbG9iYWwgcXVldWUuCiAgICAgICAgICAgICAgICAgICAgaW50YWtlRGVmaW5lcygpOwoKICAgICAgICAgICAgICAgICAgICAvL01hcmsgYWxsIHRoZSBkZXBlbmRlbmNpZXMgYXMgbmVlZGluZyB0byBiZSBsb2FkZWQuCiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5uZXh0VGljayhmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vU29tZSBkZWZpbmVzIGNvdWxkIGhhdmUgYmVlbiBhZGRlZCBzaW5jZSB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgLy9yZXF1aXJlIGNhbGwsIGNvbGxlY3QgdGhlbS4KICAgICAgICAgICAgICAgICAgICAgICAgaW50YWtlRGVmaW5lcygpOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZU1vZCA9IGdldE1vZHVsZShtYWtlTW9kdWxlTWFwKG51bGwsIHJlbE1hcCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9TdG9yZSBpZiBtYXAgY29uZmlnIHNob3VsZCBiZSBhcHBsaWVkIHRvIHRoaXMgcmVxdWlyZQogICAgICAgICAgICAgICAgICAgICAgICAvL2NhbGwgZm9yIGRlcGVuZGVuY2llcy4KICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZU1vZC5za2lwTWFwID0gb3B0aW9ucy5za2lwTWFwOwoKICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZU1vZC5pbml0KGRlcHMsIGNhbGxiYWNrLCBlcnJiYWNrLCB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tMb2FkZWQoKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsUmVxdWlyZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBtaXhpbihsb2NhbFJlcXVpcmUsIHsKICAgICAgICAgICAgICAgICAgICBpc0Jyb3dzZXI6IGlzQnJvd3NlciwKCiAgICAgICAgICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAgICAgICAgICogQ29udmVydHMgYSBtb2R1bGUgbmFtZSArIC5leHRlbnNpb24gaW50byBhbiBVUkwgcGF0aC4KICAgICAgICAgICAgICAgICAgICAgKiAqUmVxdWlyZXMqIHRoZSB1c2Ugb2YgYSBtb2R1bGUgbmFtZS4gSXQgZG9lcyBub3Qgc3VwcG9ydCB1c2luZwogICAgICAgICAgICAgICAgICAgICAqIHBsYWluIFVSTHMgbGlrZSBuYW1lVG9VcmwuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdG9Vcmw6IGZ1bmN0aW9uIChtb2R1bGVOYW1lUGx1c0V4dCkgewogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBtb2R1bGVOYW1lUGx1c0V4dC5sYXN0SW5kZXhPZignLicpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VnbWVudCA9IG1vZHVsZU5hbWVQbHVzRXh0LnNwbGl0KCcvJylbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc1JlbGF0aXZlID0gc2VnbWVudCA9PT0gJy4nIHx8IHNlZ21lbnQgPT09ICcuLic7CgogICAgICAgICAgICAgICAgICAgICAgICAvL0hhdmUgYSBmaWxlIGV4dGVuc2lvbiBhbGlhcywgYW5kIGl0IGlzIG5vdCB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgLy9kb3RzIGZyb20gYSByZWxhdGl2ZSBwYXRoLgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xICYmICghaXNSZWxhdGl2ZSB8fCBpbmRleCA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQgPSBtb2R1bGVOYW1lUGx1c0V4dC5zdWJzdHJpbmcoaW5kZXgsIG1vZHVsZU5hbWVQbHVzRXh0Lmxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lUGx1c0V4dCA9IG1vZHVsZU5hbWVQbHVzRXh0LnN1YnN0cmluZygwLCBpbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0Lm5hbWVUb1VybChub3JtYWxpemUobW9kdWxlTmFtZVBsdXNFeHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbE1hcCAmJiByZWxNYXAuaWQsIHRydWUpLCBleHQsICB0cnVlKTsKICAgICAgICAgICAgICAgICAgICB9LAoKICAgICAgICAgICAgICAgICAgICBkZWZpbmVkOiBmdW5jdGlvbiAoaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhc1Byb3AoZGVmaW5lZCwgbWFrZU1vZHVsZU1hcChpZCwgcmVsTWFwLCBmYWxzZSwgdHJ1ZSkuaWQpOwogICAgICAgICAgICAgICAgICAgIH0sCgogICAgICAgICAgICAgICAgICAgIHNwZWNpZmllZDogZnVuY3Rpb24gKGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gbWFrZU1vZHVsZU1hcChpZCwgcmVsTWFwLCBmYWxzZSwgdHJ1ZSkuaWQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBoYXNQcm9wKGRlZmluZWQsIGlkKSB8fCBoYXNQcm9wKHJlZ2lzdHJ5LCBpZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAgICAgLy9Pbmx5IGFsbG93IHVuZGVmIG9uIHRvcCBsZXZlbCByZXF1aXJlIGNhbGxzCiAgICAgICAgICAgICAgICBpZiAoIXJlbE1hcCkgewogICAgICAgICAgICAgICAgICAgIGxvY2FsUmVxdWlyZS51bmRlZiA9IGZ1bmN0aW9uIChpZCkgewogICAgICAgICAgICAgICAgICAgICAgICAvL0JpbmQgYW55IHdhaXRpbmcgZGVmaW5lKCkgY2FsbHMgdG8gdGhpcyBjb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAvL2ZpeCBmb3IgIzQwOAogICAgICAgICAgICAgICAgICAgICAgICB0YWtlR2xvYmFsUXVldWUoKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtYXAgPSBtYWtlTW9kdWxlTWFwKGlkLCByZWxNYXAsIHRydWUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kID0gZ2V0T3duKHJlZ2lzdHJ5LCBpZCk7CgogICAgICAgICAgICAgICAgICAgICAgICBtb2QudW5kZWZlZCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVNjcmlwdChpZCk7CgogICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZGVmaW5lZFtpZF07CiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB1cmxGZXRjaGVkW21hcC51cmxdOwogICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdW5kZWZFdmVudHNbaWRdOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy9DbGVhbiBxdWV1ZWQgZGVmaW5lcyB0b28uIEdvIGJhY2t3YXJkcwogICAgICAgICAgICAgICAgICAgICAgICAvL2luIGFycmF5IHNvIHRoYXQgdGhlIHNwbGljZXMgZG8gbm90CiAgICAgICAgICAgICAgICAgICAgICAgIC8vbWVzcyB1cCB0aGUgaXRlcmF0aW9uLgogICAgICAgICAgICAgICAgICAgICAgICBlYWNoUmV2ZXJzZShkZWZRdWV1ZSwgZnVuY3Rpb24oYXJncywgaSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09IGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmUXVldWUuc3BsaWNlKGksIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGNvbnRleHQuZGVmUXVldWVNYXBbaWRdOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9Ib2xkIG9uIHRvIGxpc3RlbmVycyBpbiBjYXNlIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9tb2R1bGUgd2lsbCBiZSBhdHRlbXB0ZWQgdG8gYmUgcmVsb2FkZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXNpbmcgYSBkaWZmZXJlbnQgY29uZmlnLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1vZC5ldmVudHMuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVmRXZlbnRzW2lkXSA9IG1vZC5ldmVudHM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xlYW5SZWdpc3RyeShpZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbFJlcXVpcmU7CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ2FsbGVkIHRvIGVuYWJsZSBhIG1vZHVsZSBpZiBpdCBpcyBzdGlsbCBpbiB0aGUgcmVnaXN0cnkKICAgICAgICAgICAgICogYXdhaXRpbmcgZW5hYmxlbWVudC4gQSBzZWNvbmQgYXJnLCBwYXJlbnQsIHRoZSBwYXJlbnQgbW9kdWxlLAogICAgICAgICAgICAgKiBpcyBwYXNzZWQgaW4gZm9yIGNvbnRleHQsIHdoZW4gdGhpcyBtZXRob2QgaXMgb3ZlcnJpZGRlbiBieQogICAgICAgICAgICAgKiB0aGUgb3B0aW1pemVyLiBOb3Qgc2hvd24gaGVyZSB0byBrZWVwIGNvZGUgY29tcGFjdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVuYWJsZTogZnVuY3Rpb24gKGRlcE1hcCkgewogICAgICAgICAgICAgICAgdmFyIG1vZCA9IGdldE93bihyZWdpc3RyeSwgZGVwTWFwLmlkKTsKICAgICAgICAgICAgICAgIGlmIChtb2QpIHsKICAgICAgICAgICAgICAgICAgICBnZXRNb2R1bGUoZGVwTWFwKS5lbmFibGUoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbnRlcm5hbCBtZXRob2QgdXNlZCBieSBlbnZpcm9ubWVudCBhZGFwdGVycyB0byBjb21wbGV0ZSBhIGxvYWQgZXZlbnQuCiAgICAgICAgICAgICAqIEEgbG9hZCBldmVudCBjb3VsZCBiZSBhIHNjcmlwdCBsb2FkIG9yIGp1c3QgYSBsb2FkIHBhc3MgZnJvbSBhIHN5bmNocm9ub3VzCiAgICAgICAgICAgICAqIGxvYWQgY2FsbC4KICAgICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IG1vZHVsZU5hbWUgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0byBwb3RlbnRpYWxseSBjb21wbGV0ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNvbXBsZXRlTG9hZDogZnVuY3Rpb24gKG1vZHVsZU5hbWUpIHsKICAgICAgICAgICAgICAgIHZhciBmb3VuZCwgYXJncywgbW9kLAogICAgICAgICAgICAgICAgICAgIHNoaW0gPSBnZXRPd24oY29uZmlnLnNoaW0sIG1vZHVsZU5hbWUpIHx8IHt9LAogICAgICAgICAgICAgICAgICAgIHNoRXhwb3J0cyA9IHNoaW0uZXhwb3J0czsKCiAgICAgICAgICAgICAgICB0YWtlR2xvYmFsUXVldWUoKTsKCiAgICAgICAgICAgICAgICB3aGlsZSAoZGVmUXVldWUubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgYXJncyA9IGRlZlF1ZXVlLnNoaWZ0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09IG51bGwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1swXSA9IG1vZHVsZU5hbWU7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vSWYgYWxyZWFkeSBmb3VuZCBhbiBhbm9ueW1vdXMgbW9kdWxlIGFuZCBib3VuZCBpdAogICAgICAgICAgICAgICAgICAgICAgICAvL3RvIHRoaXMgbmFtZSwgdGhlbiB0aGlzIGlzIHNvbWUgb3RoZXIgYW5vbiBtb2R1bGUKICAgICAgICAgICAgICAgICAgICAgICAgLy93YWl0aW5nIGZvciBpdHMgY29tcGxldGVMb2FkIHRvIGZpcmUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXJnc1swXSA9PT0gbW9kdWxlTmFtZSkgewogICAgICAgICAgICAgICAgICAgICAgICAvL0ZvdW5kIG1hdGNoaW5nIGRlZmluZSBjYWxsIGZvciB0aGlzIHNjcmlwdCEKICAgICAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgY2FsbEdldE1vZHVsZShhcmdzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRleHQuZGVmUXVldWVNYXAgPSB7fTsKCiAgICAgICAgICAgICAgICAvL0RvIHRoaXMgYWZ0ZXIgdGhlIGN5Y2xlIG9mIGNhbGxHZXRNb2R1bGUgaW4gY2FzZSB0aGUgcmVzdWx0CiAgICAgICAgICAgICAgICAvL29mIHRob3NlIGNhbGxzL2luaXQgY2FsbHMgY2hhbmdlcyB0aGUgcmVnaXN0cnkuCiAgICAgICAgICAgICAgICBtb2QgPSBnZXRPd24ocmVnaXN0cnksIG1vZHVsZU5hbWUpOwoKICAgICAgICAgICAgICAgIGlmICghZm91bmQgJiYgIWhhc1Byb3AoZGVmaW5lZCwgbW9kdWxlTmFtZSkgJiYgbW9kICYmICFtb2QuaW5pdGVkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbmZpZy5lbmZvcmNlRGVmaW5lICYmICghc2hFeHBvcnRzIHx8ICFnZXRHbG9iYWwoc2hFeHBvcnRzKSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1BhdGhGYWxsYmFjayhtb2R1bGVOYW1lKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IobWFrZUVycm9yKCdub2RlZmluZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdObyBkZWZpbmUgY2FsbCBmb3IgJyArIG1vZHVsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttb2R1bGVOYW1lXSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy9BIHNjcmlwdCB0aGF0IGRvZXMgbm90IGNhbGwgZGVmaW5lKCksIHNvIGp1c3Qgc2ltdWxhdGUKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGUgY2FsbCBmb3IgaXQuCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxHZXRNb2R1bGUoW21vZHVsZU5hbWUsIChzaGltLmRlcHMgfHwgW10pLCBzaGltLmV4cG9ydHNGbl0pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjaGVja0xvYWRlZCgpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgbW9kdWxlIG5hbWUgdG8gYSBmaWxlIHBhdGguIFN1cHBvcnRzIGNhc2VzIHdoZXJlCiAgICAgICAgICAgICAqIG1vZHVsZU5hbWUgbWF5IGFjdHVhbGx5IGJlIGp1c3QgYW4gVVJMLgogICAgICAgICAgICAgKiBOb3RlIHRoYXQgaXQgKipkb2VzIG5vdCoqIGNhbGwgbm9ybWFsaXplIG9uIHRoZSBtb2R1bGVOYW1lLAogICAgICAgICAgICAgKiBpdCBpcyBhc3N1bWVkIHRvIGhhdmUgYWxyZWFkeSBiZWVuIG5vcm1hbGl6ZWQuIFRoaXMgaXMgYW4KICAgICAgICAgICAgICogaW50ZXJuYWwgQVBJLCBub3QgYSBwdWJsaWMgb25lLiBVc2UgdG9VcmwgZm9yIHRoZSBwdWJsaWMgQVBJLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbmFtZVRvVXJsOiBmdW5jdGlvbiAobW9kdWxlTmFtZSwgZXh0LCBza2lwRXh0KSB7CiAgICAgICAgICAgICAgICB2YXIgcGF0aHMsIHN5bXMsIGksIHBhcmVudE1vZHVsZSwgdXJsLAogICAgICAgICAgICAgICAgICAgIHBhcmVudFBhdGgsIGJ1bmRsZUlkLAogICAgICAgICAgICAgICAgICAgIHBrZ01haW4gPSBnZXRPd24oY29uZmlnLnBrZ3MsIG1vZHVsZU5hbWUpOwoKICAgICAgICAgICAgICAgIGlmIChwa2dNYWluKSB7CiAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZSA9IHBrZ01haW47CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgYnVuZGxlSWQgPSBnZXRPd24oYnVuZGxlc01hcCwgbW9kdWxlTmFtZSk7CgogICAgICAgICAgICAgICAgaWYgKGJ1bmRsZUlkKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQubmFtZVRvVXJsKGJ1bmRsZUlkLCBleHQsIHNraXBFeHQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vSWYgYSBjb2xvbiBpcyBpbiB0aGUgVVJMLCBpdCBpbmRpY2F0ZXMgYSBwcm90b2NvbCBpcyB1c2VkIGFuZCBpdCBpcyBqdXN0CiAgICAgICAgICAgICAgICAvL2FuIFVSTCB0byBhIGZpbGUsIG9yIGlmIGl0IHN0YXJ0cyB3aXRoIGEgc2xhc2gsIGNvbnRhaW5zIGEgcXVlcnkgYXJnIChpLmUuID8pCiAgICAgICAgICAgICAgICAvL29yIGVuZHMgd2l0aCAuanMsIHRoZW4gYXNzdW1lIHRoZSB1c2VyIG1lYW50IHRvIHVzZSBhbiB1cmwgYW5kIG5vdCBhIG1vZHVsZSBpZC4KICAgICAgICAgICAgICAgIC8vVGhlIHNsYXNoIGlzIGltcG9ydGFudCBmb3IgcHJvdG9jb2wtbGVzcyBVUkxzIGFzIHdlbGwgYXMgZnVsbCBwYXRocy4KICAgICAgICAgICAgICAgIGlmIChyZXEuanNFeHRSZWdFeHAudGVzdChtb2R1bGVOYW1lKSkgewogICAgICAgICAgICAgICAgICAgIC8vSnVzdCBhIHBsYWluIHBhdGgsIG5vdCBtb2R1bGUgbmFtZSBsb29rdXAsIHNvIGp1c3QgcmV0dXJuIGl0LgogICAgICAgICAgICAgICAgICAgIC8vQWRkIGV4dGVuc2lvbiBpZiBpdCBpcyBpbmNsdWRlZC4gVGhpcyBpcyBhIGJpdCB3b25reSwgb25seSBub24tLmpzIHRoaW5ncyBwYXNzCiAgICAgICAgICAgICAgICAgICAgLy9hbiBleHRlbnNpb24sIHRoaXMgbWV0aG9kIHByb2JhYmx5IG5lZWRzIHRvIGJlIHJld29ya2VkLgogICAgICAgICAgICAgICAgICAgIHVybCA9IG1vZHVsZU5hbWUgKyAoZXh0IHx8ICcnKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLy9BIG1vZHVsZSB0aGF0IG5lZWRzIHRvIGJlIGNvbnZlcnRlZCB0byBhIHBhdGguCiAgICAgICAgICAgICAgICAgICAgcGF0aHMgPSBjb25maWcucGF0aHM7CgogICAgICAgICAgICAgICAgICAgIHN5bXMgPSBtb2R1bGVOYW1lLnNwbGl0KCcvJyk7CiAgICAgICAgICAgICAgICAgICAgLy9Gb3IgZWFjaCBtb2R1bGUgbmFtZSBzZWdtZW50LCBzZWUgaWYgdGhlcmUgaXMgYSBwYXRoCiAgICAgICAgICAgICAgICAgICAgLy9yZWdpc3RlcmVkIGZvciBpdC4gU3RhcnQgd2l0aCBtb3N0IHNwZWNpZmljIG5hbWUKICAgICAgICAgICAgICAgICAgICAvL2FuZCB3b3JrIHVwIGZyb20gaXQuCiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gc3ltcy5sZW5ndGg7IGkgPiAwOyBpIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50TW9kdWxlID0gc3ltcy5zbGljZSgwLCBpKS5qb2luKCcvJyk7CgogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRQYXRoID0gZ2V0T3duKHBhdGhzLCBwYXJlbnRNb2R1bGUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50UGF0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9JZiBhbiBhcnJheSwgaXQgbWVhbnMgdGhlcmUgYXJlIGEgZmV3IGNob2ljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL0Nob29zZSB0aGUgb25lIHRoYXQgaXMgZGVzaXJlZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkocGFyZW50UGF0aCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRQYXRoID0gcGFyZW50UGF0aFswXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bXMuc3BsaWNlKDAsIGksIHBhcmVudFBhdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vSm9pbiB0aGUgcGF0aCBwYXJ0cyB0b2dldGhlciwgdGhlbiBmaWd1cmUgb3V0IGlmIGJhc2VVcmwgaXMgbmVlZGVkLgogICAgICAgICAgICAgICAgICAgIHVybCA9IHN5bXMuam9pbignLycpOwogICAgICAgICAgICAgICAgICAgIHVybCArPSAoZXh0IHx8ICgvXmRhdGFcOnxcPy8udGVzdCh1cmwpIHx8IHNraXBFeHQgPyAnJyA6ICcuanMnKSk7CiAgICAgICAgICAgICAgICAgICAgdXJsID0gKHVybC5jaGFyQXQoMCkgPT09ICcvJyB8fCB1cmwubWF0Y2goL15bXHdcK1wuXC1dKzovKSA/ICcnIDogY29uZmlnLmJhc2VVcmwpICsgdXJsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBjb25maWcudXJsQXJncyA/IHVybCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKHVybC5pbmRleE9mKCc/JykgPT09IC0xID8gJz8nIDogJyYnKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLnVybEFyZ3MpIDogdXJsOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLy9EZWxlZ2F0ZXMgdG8gcmVxLmxvYWQuIEJyb2tlbiBvdXQgYXMgYSBzZXBhcmF0ZSBmdW5jdGlvbiB0bwogICAgICAgICAgICAvL2FsbG93IG92ZXJyaWRpbmcgaW4gdGhlIG9wdGltaXplci4KICAgICAgICAgICAgbG9hZDogZnVuY3Rpb24gKGlkLCB1cmwpIHsKICAgICAgICAgICAgICAgIHJlcS5sb2FkKGNvbnRleHQsIGlkLCB1cmwpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEV4ZWN1dGVzIGEgbW9kdWxlIGNhbGxiYWNrIGZ1bmN0aW9uLiBCcm9rZW4gb3V0IGFzIGEgc2VwYXJhdGUgZnVuY3Rpb24KICAgICAgICAgICAgICogc29sZWx5IHRvIGFsbG93IHRoZSBidWlsZCBzeXN0ZW0gdG8gc2VxdWVuY2UgdGhlIGZpbGVzIGluIHRoZSBidWlsdAogICAgICAgICAgICAgKiBsYXllciBpbiB0aGUgcmlnaHQgc2VxdWVuY2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwcml2YXRlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBleGVjQ2I6IGZ1bmN0aW9uIChuYW1lLCBjYWxsYmFjaywgYXJncywgZXhwb3J0cykgewogICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrLmFwcGx5KGV4cG9ydHMsIGFyZ3MpOwogICAgICAgICAgICB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIGNhbGxiYWNrIGZvciBzY3JpcHQgbG9hZHMsIHVzZWQgdG8gY2hlY2sgc3RhdHVzIG9mIGxvYWRpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7RXZlbnR9IGV2dCB0aGUgZXZlbnQgZnJvbSB0aGUgYnJvd3NlciBmb3IgdGhlIHNjcmlwdAogICAgICAgICAgICAgKiB0aGF0IHdhcyBsb2FkZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBvblNjcmlwdExvYWQ6IGZ1bmN0aW9uIChldnQpIHsKICAgICAgICAgICAgICAgIC8vVXNpbmcgY3VycmVudFRhcmdldCBpbnN0ZWFkIG9mIHRhcmdldCBmb3IgRmlyZWZveCAyLjAncyBzYWtlLiBOb3QKICAgICAgICAgICAgICAgIC8vYWxsIG9sZCBicm93c2VycyB3aWxsIGJlIHN1cHBvcnRlZCwgYnV0IHRoaXMgb25lIHdhcyBlYXN5IGVub3VnaAogICAgICAgICAgICAgICAgLy90byBzdXBwb3J0IGFuZCBzdGlsbCBtYWtlcyBzZW5zZS4KICAgICAgICAgICAgICAgIGlmIChldnQudHlwZSA9PT0gJ2xvYWQnIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIChyZWFkeVJlZ0V4cC50ZXN0KChldnQuY3VycmVudFRhcmdldCB8fCBldnQuc3JjRWxlbWVudCkucmVhZHlTdGF0ZSkpKSB7CiAgICAgICAgICAgICAgICAgICAgLy9SZXNldCBpbnRlcmFjdGl2ZSBzY3JpcHQgc28gYSBzY3JpcHQgbm9kZSBpcyBub3QgaGVsZCBvbnRvIGZvcgogICAgICAgICAgICAgICAgICAgIC8vdG8gbG9uZy4KICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGl2ZVNjcmlwdCA9IG51bGw7CgogICAgICAgICAgICAgICAgICAgIC8vUHVsbCBvdXQgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSBhbmQgdGhlIGNvbnRleHQuCiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBnZXRTY3JpcHREYXRhKGV2dCk7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5jb21wbGV0ZUxvYWQoZGF0YS5pZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ2FsbGJhY2sgZm9yIHNjcmlwdCBlcnJvcnMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBvblNjcmlwdEVycm9yOiBmdW5jdGlvbiAoZXZ0KSB7CiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IGdldFNjcmlwdERhdGEoZXZ0KTsKICAgICAgICAgICAgICAgIGlmICghaGFzUGF0aEZhbGxiYWNrKGRhdGEuaWQpKSB7CiAgICAgICAgICAgICAgICAgICAgdmFyIHBhcmVudHMgPSBbXTsKICAgICAgICAgICAgICAgICAgICBlYWNoUHJvcChyZWdpc3RyeSwgZnVuY3Rpb24odmFsdWUsIGtleSkgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5LmluZGV4T2YoJ19AcicpICE9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYWNoKHZhbHVlLmRlcE1hcHMsIGZ1bmN0aW9uKGRlcE1hcCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXBNYXAuaWQgPT09IGRhdGEuaWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50cy5wdXNoKGtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gb25FcnJvcihtYWtlRXJyb3IoJ3NjcmlwdGVycm9yJywgJ1NjcmlwdCBlcnJvciBmb3IgIicgKyBkYXRhLmlkICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHBhcmVudHMubGVuZ3RoID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyIsIG5lZWRlZCBieTogJyArIHBhcmVudHMuam9pbignLCAnKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICciJyksIGV2dCwgW2RhdGEuaWRdKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9OwoKICAgICAgICBjb250ZXh0LnJlcXVpcmUgPSBjb250ZXh0Lm1ha2VSZXF1aXJlKCk7CiAgICAgICAgcmV0dXJuIGNvbnRleHQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWluIGVudHJ5IHBvaW50LgogICAgICoKICAgICAqIElmIHRoZSBvbmx5IGFyZ3VtZW50IHRvIHJlcXVpcmUgaXMgYSBzdHJpbmcsIHRoZW4gdGhlIG1vZHVsZSB0aGF0CiAgICAgKiBpcyByZXByZXNlbnRlZCBieSB0aGF0IHN0cmluZyBpcyBmZXRjaGVkIGZvciB0aGUgYXBwcm9wcmlhdGUgY29udGV4dC4KICAgICAqCiAgICAgKiBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gYXJyYXksIHRoZW4gaXQgd2lsbCBiZSB0cmVhdGVkIGFzIGFuIGFycmF5CiAgICAgKiBvZiBkZXBlbmRlbmN5IHN0cmluZyBuYW1lcyB0byBmZXRjaC4gQW4gb3B0aW9uYWwgZnVuY3Rpb24gY2FsbGJhY2sgY2FuCiAgICAgKiBiZSBzcGVjaWZpZWQgdG8gZXhlY3V0ZSB3aGVuIGFsbCBvZiB0aG9zZSBkZXBlbmRlbmNpZXMgYXJlIGF2YWlsYWJsZS4KICAgICAqCiAgICAgKiBNYWtlIGEgbG9jYWwgcmVxIHZhcmlhYmxlIHRvIGhlbHAgQ2FqYSBjb21wbGlhbmNlIChpdCBhc3N1bWVzIHRoaW5ncwogICAgICogb24gYSByZXF1aXJlIHRoYXQgYXJlIG5vdCBzdGFuZGFyZGl6ZWQpLCBhbmQgdG8gZ2l2ZSBhIHNob3J0CiAgICAgKiBuYW1lIGZvciBtaW5pZmljYXRpb24vbG9jYWwgc2NvcGUgdXNlLgogICAgICovCiAgICByZXEgPSByZXF1aXJlanMgPSBmdW5jdGlvbiAoZGVwcywgY2FsbGJhY2ssIGVycmJhY2ssIG9wdGlvbmFsKSB7CgogICAgICAgIC8vRmluZCB0aGUgcmlnaHQgY29udGV4dCwgdXNlIGRlZmF1bHQKICAgICAgICB2YXIgY29udGV4dCwgY29uZmlnLAogICAgICAgICAgICBjb250ZXh0TmFtZSA9IGRlZkNvbnRleHROYW1lOwoKICAgICAgICAvLyBEZXRlcm1pbmUgaWYgaGF2ZSBjb25maWcgb2JqZWN0IGluIHRoZSBjYWxsLgogICAgICAgIGlmICghaXNBcnJheShkZXBzKSAmJiB0eXBlb2YgZGVwcyAhPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgLy8gZGVwcyBpcyBhIGNvbmZpZyBvYmplY3QKICAgICAgICAgICAgY29uZmlnID0gZGVwczsKICAgICAgICAgICAgaWYgKGlzQXJyYXkoY2FsbGJhY2spKSB7CiAgICAgICAgICAgICAgICAvLyBBZGp1c3QgYXJncyBpZiB0aGVyZSBhcmUgZGVwZW5kZW5jaWVzCiAgICAgICAgICAgICAgICBkZXBzID0gY2FsbGJhY2s7CiAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGVycmJhY2s7CiAgICAgICAgICAgICAgICBlcnJiYWNrID0gb3B0aW9uYWw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBkZXBzID0gW107CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChjb25maWcgJiYgY29uZmlnLmNvbnRleHQpIHsKICAgICAgICAgICAgY29udGV4dE5hbWUgPSBjb25maWcuY29udGV4dDsKICAgICAgICB9CgogICAgICAgIGNvbnRleHQgPSBnZXRPd24oY29udGV4dHMsIGNvbnRleHROYW1lKTsKICAgICAgICBpZiAoIWNvbnRleHQpIHsKICAgICAgICAgICAgY29udGV4dCA9IGNvbnRleHRzW2NvbnRleHROYW1lXSA9IHJlcS5zLm5ld0NvbnRleHQoY29udGV4dE5hbWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNvbmZpZykgewogICAgICAgICAgICBjb250ZXh0LmNvbmZpZ3VyZShjb25maWcpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIGNvbnRleHQucmVxdWlyZShkZXBzLCBjYWxsYmFjaywgZXJyYmFjayk7CiAgICB9OwoKICAgIC8qKgogICAgICogU3VwcG9ydCByZXF1aXJlLmNvbmZpZygpIHRvIG1ha2UgaXQgZWFzaWVyIHRvIGNvb3BlcmF0ZSB3aXRoIG90aGVyCiAgICAgKiBBTUQgbG9hZGVycyBvbiBnbG9iYWxseSBhZ3JlZWQgbmFtZXMuCiAgICAgKi8KICAgIHJlcS5jb25maWcgPSBmdW5jdGlvbiAoY29uZmlnKSB7CiAgICAgICAgcmV0dXJuIHJlcShjb25maWcpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4ZWN1dGUgc29tZXRoaW5nIGFmdGVyIHRoZSBjdXJyZW50IHRpY2sKICAgICAqIG9mIHRoZSBldmVudCBsb29wLiBPdmVycmlkZSBmb3Igb3RoZXIgZW52cwogICAgICogdGhhdCBoYXZlIGEgYmV0dGVyIHNvbHV0aW9uIHRoYW4gc2V0VGltZW91dC4KICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmbiBmdW5jdGlvbiB0byBleGVjdXRlIGxhdGVyLgogICAgICovCiAgICByZXEubmV4dFRpY2sgPSB0eXBlb2Ygc2V0VGltZW91dCAhPT0gJ3VuZGVmaW5lZCcgPyBmdW5jdGlvbiAoZm4pIHsKICAgICAgICBzZXRUaW1lb3V0KGZuLCA0KTsKICAgIH0gOiBmdW5jdGlvbiAoZm4pIHsgZm4oKTsgfTsKCiAgICAvKioKICAgICAqIEV4cG9ydCByZXF1aXJlIGFzIGEgZ2xvYmFsLCBidXQgb25seSBpZiBpdCBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0LgogICAgICovCiAgICBpZiAoIXJlcXVpcmUpIHsKICAgICAgICByZXF1aXJlID0gcmVxOwogICAgfQoKICAgIHJlcS52ZXJzaW9uID0gdmVyc2lvbjsKCiAgICAvL1VzZWQgdG8gZmlsdGVyIG91dCBkZXBlbmRlbmNpZXMgdGhhdCBhcmUgYWxyZWFkeSBwYXRocy4KICAgIHJlcS5qc0V4dFJlZ0V4cCA9IC9eXC98OnxcP3xcLmpzJC87CiAgICByZXEuaXNCcm93c2VyID0gaXNCcm93c2VyOwogICAgcyA9IHJlcS5zID0gewogICAgICAgIGNvbnRleHRzOiBjb250ZXh0cywKICAgICAgICBuZXdDb250ZXh0OiBuZXdDb250ZXh0CiAgICB9OwoKICAgIC8vQ3JlYXRlIGRlZmF1bHQgY29udGV4dC4KICAgIHJlcSh7fSk7CgogICAgLy9FeHBvcnRzIHNvbWUgY29udGV4dC1zZW5zaXRpdmUgbWV0aG9kcyBvbiBnbG9iYWwgcmVxdWlyZS4KICAgIGVhY2goWwogICAgICAgICd0b1VybCcsCiAgICAgICAgJ3VuZGVmJywKICAgICAgICAnZGVmaW5lZCcsCiAgICAgICAgJ3NwZWNpZmllZCcKICAgIF0sIGZ1bmN0aW9uIChwcm9wKSB7CiAgICAgICAgLy9SZWZlcmVuY2UgZnJvbSBjb250ZXh0cyBpbnN0ZWFkIG9mIGVhcmx5IGJpbmRpbmcgdG8gZGVmYXVsdCBjb250ZXh0LAogICAgICAgIC8vc28gdGhhdCBkdXJpbmcgYnVpbGRzLCB0aGUgbGF0ZXN0IGluc3RhbmNlIG9mIHRoZSBkZWZhdWx0IGNvbnRleHQKICAgICAgICAvL3dpdGggaXRzIGNvbmZpZyBnZXRzIHVzZWQuCiAgICAgICAgcmVxW3Byb3BdID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICB2YXIgY3R4ID0gY29udGV4dHNbZGVmQ29udGV4dE5hbWVdOwogICAgICAgICAgICByZXR1cm4gY3R4LnJlcXVpcmVbcHJvcF0uYXBwbHkoY3R4LCBhcmd1bWVudHMpOwogICAgICAgIH07CiAgICB9KTsKCiAgICBpZiAoaXNCcm93c2VyKSB7CiAgICAgICAgaGVhZCA9IHMuaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07CiAgICAgICAgLy9JZiBCQVNFIHRhZyBpcyBpbiBwbGF5LCB1c2luZyBhcHBlbmRDaGlsZCBpcyBhIHByb2JsZW0gZm9yIElFNi4KICAgICAgICAvL1doZW4gdGhhdCBicm93c2VyIGRpZXMsIHRoaXMgY2FuIGJlIHJlbW92ZWQuIERldGFpbHMgaW4gdGhpcyBqUXVlcnkgYnVnOgogICAgICAgIC8vaHR0cDovL2Rldi5qcXVlcnkuY29tL3RpY2tldC8yNzA5CiAgICAgICAgYmFzZUVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnYmFzZScpWzBdOwogICAgICAgIGlmIChiYXNlRWxlbWVudCkgewogICAgICAgICAgICBoZWFkID0gcy5oZWFkID0gYmFzZUVsZW1lbnQucGFyZW50Tm9kZTsKICAgICAgICB9CiAgICB9CgogICAgLyoqCiAgICAgKiBBbnkgZXJyb3JzIHRoYXQgcmVxdWlyZSBleHBsaWNpdGx5IGdlbmVyYXRlcyB3aWxsIGJlIHBhc3NlZCB0byB0aGlzCiAgICAgKiBmdW5jdGlvbi4gSW50ZXJjZXB0L292ZXJyaWRlIGl0IGlmIHlvdSB3YW50IGN1c3RvbSBlcnJvciBoYW5kbGluZy4KICAgICAqIEBwYXJhbSB7RXJyb3J9IGVyciB0aGUgZXJyb3Igb2JqZWN0LgogICAgICovCiAgICByZXEub25FcnJvciA9IGRlZmF1bHRPbkVycm9yOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyB0aGUgbm9kZSBmb3IgdGhlIGxvYWQgY29tbWFuZC4gT25seSB1c2VkIGluIGJyb3dzZXIgZW52cy4KICAgICAqLwogICAgcmVxLmNyZWF0ZU5vZGUgPSBmdW5jdGlvbiAoY29uZmlnLCBtb2R1bGVOYW1lLCB1cmwpIHsKICAgICAgICB2YXIgbm9kZSA9IGNvbmZpZy54aHRtbCA/CiAgICAgICAgICAgICAgICBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnLCAnaHRtbDpzY3JpcHQnKSA6CiAgICAgICAgICAgICAgICBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsKICAgICAgICBub2RlLnR5cGUgPSBjb25maWcuc2NyaXB0VHlwZSB8fCAndGV4dC9qYXZhc2NyaXB0JzsKICAgICAgICBub2RlLmNoYXJzZXQgPSAndXRmLTgnOwogICAgICAgIG5vZGUuYXN5bmMgPSB0cnVlOwogICAgICAgIHJldHVybiBub2RlOwogICAgfTsKCiAgICAvKioKICAgICAqIERvZXMgdGhlIHJlcXVlc3QgdG8gbG9hZCBhIG1vZHVsZSBmb3IgdGhlIGJyb3dzZXIgY2FzZS4KICAgICAqIE1ha2UgdGhpcyBhIHNlcGFyYXRlIGZ1bmN0aW9uIHRvIGFsbG93IG90aGVyIGVudmlyb25tZW50cwogICAgICogdG8gb3ZlcnJpZGUgaXQuCiAgICAgKgogICAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQgdGhlIHJlcXVpcmUgY29udGV4dCB0byBmaW5kIHN0YXRlLgogICAgICogQHBhcmFtIHtTdHJpbmd9IG1vZHVsZU5hbWUgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZS4KICAgICAqIEBwYXJhbSB7T2JqZWN0fSB1cmwgdGhlIFVSTCB0byB0aGUgbW9kdWxlLgogICAgICovCiAgICByZXEubG9hZCA9IGZ1bmN0aW9uIChjb250ZXh0LCBtb2R1bGVOYW1lLCB1cmwpIHsKICAgICAgICB2YXIgY29uZmlnID0gKGNvbnRleHQgJiYgY29udGV4dC5jb25maWcpIHx8IHt9LAogICAgICAgICAgICBub2RlOwogICAgICAgIGlmIChpc0Jyb3dzZXIpIHsKICAgICAgICAgICAgLy9JbiB0aGUgYnJvd3NlciBzbyB1c2UgYSBzY3JpcHQgdGFnCiAgICAgICAgICAgIG5vZGUgPSByZXEuY3JlYXRlTm9kZShjb25maWcsIG1vZHVsZU5hbWUsIHVybCk7CiAgICAgICAgICAgIGlmIChjb25maWcub25Ob2RlQ3JlYXRlZCkgewogICAgICAgICAgICAgICAgY29uZmlnLm9uTm9kZUNyZWF0ZWQobm9kZSwgY29uZmlnLCBtb2R1bGVOYW1lLCB1cmwpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgnZGF0YS1yZXF1aXJlY29udGV4dCcsIGNvbnRleHQuY29udGV4dE5hbWUpOwogICAgICAgICAgICBub2RlLnNldEF0dHJpYnV0ZSgnZGF0YS1yZXF1aXJlbW9kdWxlJywgbW9kdWxlTmFtZSk7CgogICAgICAgICAgICAvL1NldCB1cCBsb2FkIGxpc3RlbmVyLiBUZXN0IGF0dGFjaEV2ZW50IGZpcnN0IGJlY2F1c2UgSUU5IGhhcwogICAgICAgICAgICAvL2Egc3VidGxlIGlzc3VlIGluIGl0cyBhZGRFdmVudExpc3RlbmVyIGFuZCBzY3JpcHQgb25sb2FkIGZpcmluZ3MKICAgICAgICAgICAgLy90aGF0IGRvIG5vdCBtYXRjaCB0aGUgYmVoYXZpb3Igb2YgYWxsIG90aGVyIGJyb3dzZXJzIHdpdGgKICAgICAgICAgICAgLy9hZGRFdmVudExpc3RlbmVyIHN1cHBvcnQsIHdoaWNoIGZpcmUgdGhlIG9ubG9hZCBldmVudCBmb3IgYQogICAgICAgICAgICAvL3NjcmlwdCByaWdodCBhZnRlciB0aGUgc2NyaXB0IGV4ZWN1dGlvbi4gU2VlOgogICAgICAgICAgICAvL2h0dHBzOi8vY29ubmVjdC5taWNyb3NvZnQuY29tL0lFL2ZlZWRiYWNrL2RldGFpbHMvNjQ4MDU3L3NjcmlwdC1vbmxvYWQtZXZlbnQtaXMtbm90LWZpcmVkLWltbWVkaWF0ZWx5LWFmdGVyLXNjcmlwdC1leGVjdXRpb24KICAgICAgICAgICAgLy9VTkZPUlRVTkFURUxZIE9wZXJhIGltcGxlbWVudHMgYXR0YWNoRXZlbnQgYnV0IGRvZXMgbm90IGZvbGxvdyB0aGUgc2NyaXB0CiAgICAgICAgICAgIC8vc2NyaXB0IGV4ZWN1dGlvbiBtb2RlLgogICAgICAgICAgICBpZiAobm9kZS5hdHRhY2hFdmVudCAmJgogICAgICAgICAgICAgICAgICAgIC8vQ2hlY2sgaWYgbm9kZS5hdHRhY2hFdmVudCBpcyBhcnRpZmljaWFsbHkgYWRkZWQgYnkgY3VzdG9tIHNjcmlwdCBvcgogICAgICAgICAgICAgICAgICAgIC8vbmF0aXZlbHkgc3VwcG9ydGVkIGJ5IGJyb3dzZXIKICAgICAgICAgICAgICAgICAgICAvL3JlYWQgaHR0cHM6Ly9naXRodWIuY29tL2pyYnVya2UvcmVxdWlyZWpzL2lzc3Vlcy8xODcKICAgICAgICAgICAgICAgICAgICAvL2lmIHdlIGNhbiBOT1QgZmluZCBbbmF0aXZlIGNvZGVdIHRoZW4gaXQgbXVzdCBOT1QgbmF0aXZlbHkgc3VwcG9ydGVkLgogICAgICAgICAgICAgICAgICAgIC8vaW4gSUU4LCBub2RlLmF0dGFjaEV2ZW50IGRvZXMgbm90IGhhdmUgdG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgIC8vTm90ZSB0aGUgdGVzdCBmb3IgIltuYXRpdmUgY29kZSIgd2l0aCBubyBjbG9zaW5nIGJyYWNlLCBzZWU6CiAgICAgICAgICAgICAgICAgICAgLy9odHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvaXNzdWVzLzI3MwogICAgICAgICAgICAgICAgICAgICEobm9kZS5hdHRhY2hFdmVudC50b1N0cmluZyAmJiBub2RlLmF0dGFjaEV2ZW50LnRvU3RyaW5nKCkuaW5kZXhPZignW25hdGl2ZSBjb2RlJykgPCAwKSAmJgogICAgICAgICAgICAgICAgICAgICFpc09wZXJhKSB7CiAgICAgICAgICAgICAgICAvL1Byb2JhYmx5IElFLiBJRSAoYXQgbGVhc3QgNi04KSBkbyBub3QgZmlyZQogICAgICAgICAgICAgICAgLy9zY3JpcHQgb25sb2FkIHJpZ2h0IGFmdGVyIGV4ZWN1dGluZyB0aGUgc2NyaXB0LCBzbwogICAgICAgICAgICAgICAgLy93ZSBjYW5ub3QgdGllIHRoZSBhbm9ueW1vdXMgZGVmaW5lIGNhbGwgdG8gYSBuYW1lLgogICAgICAgICAgICAgICAgLy9Ib3dldmVyLCBJRSByZXBvcnRzIHRoZSBzY3JpcHQgYXMgYmVpbmcgaW4gJ2ludGVyYWN0aXZlJwogICAgICAgICAgICAgICAgLy9yZWFkeVN0YXRlIGF0IHRoZSB0aW1lIG9mIHRoZSBkZWZpbmUgY2FsbC4KICAgICAgICAgICAgICAgIHVzZUludGVyYWN0aXZlID0gdHJ1ZTsKCiAgICAgICAgICAgICAgICBub2RlLmF0dGFjaEV2ZW50KCdvbnJlYWR5c3RhdGVjaGFuZ2UnLCBjb250ZXh0Lm9uU2NyaXB0TG9hZCk7CiAgICAgICAgICAgICAgICAvL0l0IHdvdWxkIGJlIGdyZWF0IHRvIGFkZCBhbiBlcnJvciBoYW5kbGVyIGhlcmUgdG8gY2F0Y2gKICAgICAgICAgICAgICAgIC8vNDA0cyBpbiBJRTkrLiBIb3dldmVyLCBvbnJlYWR5c3RhdGVjaGFuZ2Ugd2lsbCBmaXJlIGJlZm9yZQogICAgICAgICAgICAgICAgLy90aGUgZXJyb3IgaGFuZGxlciwgc28gdGhhdCBkb2VzIG5vdCBoZWxwLiBJZiBhZGRFdmVudExpc3RlbmVyCiAgICAgICAgICAgICAgICAvL2lzIHVzZWQsIHRoZW4gSUUgd2lsbCBmaXJlIGVycm9yIGJlZm9yZSBsb2FkLCBidXQgd2UgY2Fubm90CiAgICAgICAgICAgICAgICAvL3VzZSB0aGF0IHBhdGh3YXkgZ2l2ZW4gdGhlIGNvbm5lY3QubWljcm9zb2Z0LmNvbSBpc3N1ZQogICAgICAgICAgICAgICAgLy9tZW50aW9uZWQgYWJvdmUgYWJvdXQgbm90IGRvaW5nIHRoZSAnc2NyaXB0IGV4ZWN1dGUsCiAgICAgICAgICAgICAgICAvL3RoZW4gZmlyZSB0aGUgc2NyaXB0IGxvYWQgZXZlbnQgbGlzdGVuZXIgYmVmb3JlIGV4ZWN1dGUKICAgICAgICAgICAgICAgIC8vbmV4dCBzY3JpcHQnIHRoYXQgb3RoZXIgYnJvd3NlcnMgZG8uCiAgICAgICAgICAgICAgICAvL0Jlc3QgaG9wZTogSUUxMCBmaXhlcyB0aGUgaXNzdWVzLAogICAgICAgICAgICAgICAgLy9hbmQgdGhlbiBkZXN0cm95cyBhbGwgaW5zdGFsbHMgb2YgSUUgNi05LgogICAgICAgICAgICAgICAgLy9ub2RlLmF0dGFjaEV2ZW50KCdvbmVycm9yJywgY29udGV4dC5vblNjcmlwdEVycm9yKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGNvbnRleHQub25TY3JpcHRMb2FkLCBmYWxzZSk7CiAgICAgICAgICAgICAgICBub2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgY29udGV4dC5vblNjcmlwdEVycm9yLCBmYWxzZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbm9kZS5zcmMgPSB1cmw7CgogICAgICAgICAgICAvL0ZvciBzb21lIGNhY2hlIGNhc2VzIGluIElFIDYtOCwgdGhlIHNjcmlwdCBleGVjdXRlcyBiZWZvcmUgdGhlIGVuZAogICAgICAgICAgICAvL29mIHRoZSBhcHBlbmRDaGlsZCBleGVjdXRpb24sIHNvIHRvIHRpZSBhbiBhbm9ueW1vdXMgZGVmaW5lCiAgICAgICAgICAgIC8vY2FsbCB0byB0aGUgbW9kdWxlIG5hbWUgKHdoaWNoIGlzIHN0b3JlZCBvbiB0aGUgbm9kZSksIGhvbGQgb24KICAgICAgICAgICAgLy90byBhIHJlZmVyZW5jZSB0byB0aGlzIG5vZGUsIGJ1dCBjbGVhciBhZnRlciB0aGUgRE9NIGluc2VydGlvbi4KICAgICAgICAgICAgY3VycmVudGx5QWRkaW5nU2NyaXB0ID0gbm9kZTsKICAgICAgICAgICAgaWYgKGJhc2VFbGVtZW50KSB7CiAgICAgICAgICAgICAgICBoZWFkLmluc2VydEJlZm9yZShub2RlLCBiYXNlRWxlbWVudCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBoZWFkLmFwcGVuZENoaWxkKG5vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJlbnRseUFkZGluZ1NjcmlwdCA9IG51bGw7CgogICAgICAgICAgICByZXR1cm4gbm9kZTsKICAgICAgICB9IGVsc2UgaWYgKGlzV2ViV29ya2VyKSB7CiAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAvL0luIGEgd2ViIHdvcmtlciwgdXNlIGltcG9ydFNjcmlwdHMuIFRoaXMgaXMgbm90IGEgdmVyeQogICAgICAgICAgICAgICAgLy9lZmZpY2llbnQgdXNlIG9mIGltcG9ydFNjcmlwdHMsIGltcG9ydFNjcmlwdHMgd2lsbCBibG9jayB1bnRpbAogICAgICAgICAgICAgICAgLy9pdHMgc2NyaXB0IGlzIGRvd25sb2FkZWQgYW5kIGV2YWx1YXRlZC4gSG93ZXZlciwgaWYgd2ViIHdvcmtlcnMKICAgICAgICAgICAgICAgIC8vYXJlIGluIHBsYXksIHRoZSBleHBlY3RhdGlvbiBpcyB0aGF0IGEgYnVpbGQgaGFzIGJlZW4gZG9uZSBzbwogICAgICAgICAgICAgICAgLy90aGF0IG9ubHkgb25lIHNjcmlwdCBuZWVkcyB0byBiZSBsb2FkZWQgYW55d2F5LiBUaGlzIG1heSBuZWVkCiAgICAgICAgICAgICAgICAvL3RvIGJlIHJlZXZhbHVhdGVkIGlmIG90aGVyIHVzZSBjYXNlcyBiZWNvbWUgY29tbW9uLgogICAgICAgICAgICAgICAgaW1wb3J0U2NyaXB0cyh1cmwpOwoKICAgICAgICAgICAgICAgIC8vQWNjb3VudCBmb3IgYW5vbnltb3VzIG1vZHVsZXMKICAgICAgICAgICAgICAgIGNvbnRleHQuY29tcGxldGVMb2FkKG1vZHVsZU5hbWUpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgICBjb250ZXh0Lm9uRXJyb3IobWFrZUVycm9yKCdpbXBvcnRzY3JpcHRzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnaW1wb3J0U2NyaXB0cyBmYWlsZWQgZm9yICcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2R1bGVOYW1lICsgJyBhdCAnICsgdXJsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21vZHVsZU5hbWVdKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9OwoKICAgIGZ1bmN0aW9uIGdldEludGVyYWN0aXZlU2NyaXB0KCkgewogICAgICAgIGlmIChpbnRlcmFjdGl2ZVNjcmlwdCAmJiBpbnRlcmFjdGl2ZVNjcmlwdC5yZWFkeVN0YXRlID09PSAnaW50ZXJhY3RpdmUnKSB7CiAgICAgICAgICAgIHJldHVybiBpbnRlcmFjdGl2ZVNjcmlwdDsKICAgICAgICB9CgogICAgICAgIGVhY2hSZXZlcnNlKHNjcmlwdHMoKSwgZnVuY3Rpb24gKHNjcmlwdCkgewogICAgICAgICAgICBpZiAoc2NyaXB0LnJlYWR5U3RhdGUgPT09ICdpbnRlcmFjdGl2ZScpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoaW50ZXJhY3RpdmVTY3JpcHQgPSBzY3JpcHQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIGludGVyYWN0aXZlU2NyaXB0OwogICAgfQoKICAgIC8vTG9vayBmb3IgYSBkYXRhLW1haW4gc2NyaXB0IGF0dHJpYnV0ZSwgd2hpY2ggY291bGQgYWxzbyBhZGp1c3QgdGhlIGJhc2VVcmwuCiAgICBpZiAoaXNCcm93c2VyICYmICFjZmcuc2tpcERhdGFNYWluKSB7CiAgICAgICAgLy9GaWd1cmUgb3V0IGJhc2VVcmwuIEdldCBpdCBmcm9tIHRoZSBzY3JpcHQgdGFnIHdpdGggcmVxdWlyZS5qcyBpbiBpdC4KICAgICAgICBlYWNoUmV2ZXJzZShzY3JpcHRzKCksIGZ1bmN0aW9uIChzY3JpcHQpIHsKICAgICAgICAgICAgLy9TZXQgdGhlICdoZWFkJyB3aGVyZSB3ZSBjYW4gYXBwZW5kIGNoaWxkcmVuIGJ5CiAgICAgICAgICAgIC8vdXNpbmcgdGhlIHNjcmlwdCdzIHBhcmVudC4KICAgICAgICAgICAgaWYgKCFoZWFkKSB7CiAgICAgICAgICAgICAgICBoZWFkID0gc2NyaXB0LnBhcmVudE5vZGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vTG9vayBmb3IgYSBkYXRhLW1haW4gYXR0cmlidXRlIHRvIHNldCBtYWluIHNjcmlwdCBmb3IgdGhlIHBhZ2UKICAgICAgICAgICAgLy90byBsb2FkLiBJZiBpdCBpcyB0aGVyZSwgdGhlIHBhdGggdG8gZGF0YSBtYWluIGJlY29tZXMgdGhlCiAgICAgICAgICAgIC8vYmFzZVVybCwgaWYgaXQgaXMgbm90IGFscmVhZHkgc2V0LgogICAgICAgICAgICBkYXRhTWFpbiA9IHNjcmlwdC5nZXRBdHRyaWJ1dGUoJ2RhdGEtbWFpbicpOwogICAgICAgICAgICBpZiAoZGF0YU1haW4pIHsKICAgICAgICAgICAgICAgIC8vUHJlc2VydmUgZGF0YU1haW4gaW4gY2FzZSBpdCBpcyBhIHBhdGggKGkuZS4gY29udGFpbnMgJz8nKQogICAgICAgICAgICAgICAgbWFpblNjcmlwdCA9IGRhdGFNYWluOwoKICAgICAgICAgICAgICAgIC8vU2V0IGZpbmFsIGJhc2VVcmwgaWYgdGhlcmUgaXMgbm90IGFscmVhZHkgYW4gZXhwbGljaXQgb25lLgogICAgICAgICAgICAgICAgaWYgKCFjZmcuYmFzZVVybCkgewogICAgICAgICAgICAgICAgICAgIC8vUHVsbCBvZmYgdGhlIGRpcmVjdG9yeSBvZiBkYXRhLW1haW4gZm9yIHVzZSBhcyB0aGUKICAgICAgICAgICAgICAgICAgICAvL2Jhc2VVcmwuCiAgICAgICAgICAgICAgICAgICAgc3JjID0gbWFpblNjcmlwdC5zcGxpdCgnLycpOwogICAgICAgICAgICAgICAgICAgIG1haW5TY3JpcHQgPSBzcmMucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgc3ViUGF0aCA9IHNyYy5sZW5ndGggPyBzcmMuam9pbignLycpICArICcvJyA6ICcuLyc7CgogICAgICAgICAgICAgICAgICAgIGNmZy5iYXNlVXJsID0gc3ViUGF0aDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL1N0cmlwIG9mZiBhbnkgdHJhaWxpbmcgLmpzIHNpbmNlIG1haW5TY3JpcHQgaXMgbm93CiAgICAgICAgICAgICAgICAvL2xpa2UgYSBtb2R1bGUgbmFtZS4KICAgICAgICAgICAgICAgIG1haW5TY3JpcHQgPSBtYWluU2NyaXB0LnJlcGxhY2UoanNTdWZmaXhSZWdFeHAsICcnKTsKCiAgICAgICAgICAgICAgICAvL0lmIG1haW5TY3JpcHQgaXMgc3RpbGwgYSBwYXRoLCBmYWxsIGJhY2sgdG8gZGF0YU1haW4KICAgICAgICAgICAgICAgIGlmIChyZXEuanNFeHRSZWdFeHAudGVzdChtYWluU2NyaXB0KSkgewogICAgICAgICAgICAgICAgICAgIG1haW5TY3JpcHQgPSBkYXRhTWFpbjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL1B1dCB0aGUgZGF0YS1tYWluIHNjcmlwdCBpbiB0aGUgZmlsZXMgdG8gbG9hZC4KICAgICAgICAgICAgICAgIGNmZy5kZXBzID0gY2ZnLmRlcHMgPyBjZmcuZGVwcy5jb25jYXQobWFpblNjcmlwdCkgOiBbbWFpblNjcmlwdF07CgogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSBmdW5jdGlvbiB0aGF0IGhhbmRsZXMgZGVmaW5pdGlvbnMgb2YgbW9kdWxlcy4gRGlmZmVycyBmcm9tCiAgICAgKiByZXF1aXJlKCkgaW4gdGhhdCBhIHN0cmluZyBmb3IgdGhlIG1vZHVsZSBzaG91bGQgYmUgdGhlIGZpcnN0IGFyZ3VtZW50LAogICAgICogYW5kIHRoZSBmdW5jdGlvbiB0byBleGVjdXRlIGFmdGVyIGRlcGVuZGVuY2llcyBhcmUgbG9hZGVkIHNob3VsZAogICAgICogcmV0dXJuIGEgdmFsdWUgdG8gZGVmaW5lIHRoZSBtb2R1bGUgY29ycmVzcG9uZGluZyB0byB0aGUgZmlyc3QgYXJndW1lbnQncwogICAgICogbmFtZS4KICAgICAqLwogICAgZGVmaW5lID0gZnVuY3Rpb24gKG5hbWUsIGRlcHMsIGNhbGxiYWNrKSB7CiAgICAgICAgdmFyIG5vZGUsIGNvbnRleHQ7CgogICAgICAgIC8vQWxsb3cgZm9yIGFub255bW91cyBtb2R1bGVzCiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykgewogICAgICAgICAgICAvL0FkanVzdCBhcmdzIGFwcHJvcHJpYXRlbHkKICAgICAgICAgICAgY2FsbGJhY2sgPSBkZXBzOwogICAgICAgICAgICBkZXBzID0gbmFtZTsKICAgICAgICAgICAgbmFtZSA9IG51bGw7CiAgICAgICAgfQoKICAgICAgICAvL1RoaXMgbW9kdWxlIG1heSBub3QgaGF2ZSBkZXBlbmRlbmNpZXMKICAgICAgICBpZiAoIWlzQXJyYXkoZGVwcykpIHsKICAgICAgICAgICAgY2FsbGJhY2sgPSBkZXBzOwogICAgICAgICAgICBkZXBzID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIC8vSWYgbm8gbmFtZSwgYW5kIGNhbGxiYWNrIGlzIGEgZnVuY3Rpb24sIHRoZW4gZmlndXJlIG91dCBpZiBpdCBhCiAgICAgICAgLy9Db21tb25KUyB0aGluZyB3aXRoIGRlcGVuZGVuY2llcy4KICAgICAgICBpZiAoIWRlcHMgJiYgaXNGdW5jdGlvbihjYWxsYmFjaykpIHsKICAgICAgICAgICAgZGVwcyA9IFtdOwogICAgICAgICAgICAvL1JlbW92ZSBjb21tZW50cyBmcm9tIHRoZSBjYWxsYmFjayBzdHJpbmcsCiAgICAgICAgICAgIC8vbG9vayBmb3IgcmVxdWlyZSBjYWxscywgYW5kIHB1bGwgdGhlbSBpbnRvIHRoZSBkZXBlbmRlbmNpZXMsCiAgICAgICAgICAgIC8vYnV0IG9ubHkgaWYgdGhlcmUgYXJlIGZ1bmN0aW9uIGFyZ3MuCiAgICAgICAgICAgIGlmIChjYWxsYmFjay5sZW5ndGgpIHsKICAgICAgICAgICAgICAgIGNhbGxiYWNrCiAgICAgICAgICAgICAgICAgICAgLnRvU3RyaW5nKCkKICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShjb21tZW50UmVnRXhwLCAnJykKICAgICAgICAgICAgICAgICAgICAucmVwbGFjZShjanNSZXF1aXJlUmVnRXhwLCBmdW5jdGlvbiAobWF0Y2gsIGRlcCkgewogICAgICAgICAgICAgICAgICAgICAgICBkZXBzLnB1c2goZGVwKTsKICAgICAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICAvL01heSBiZSBhIENvbW1vbkpTIHRoaW5nIGV2ZW4gd2l0aG91dCByZXF1aXJlIGNhbGxzLCBidXQgc3RpbGwKICAgICAgICAgICAgICAgIC8vY291bGQgdXNlIGV4cG9ydHMsIGFuZCBtb2R1bGUuIEF2b2lkIGRvaW5nIGV4cG9ydHMgYW5kIG1vZHVsZQogICAgICAgICAgICAgICAgLy93b3JrIHRob3VnaCBpZiBpdCBqdXN0IG5lZWRzIHJlcXVpcmUuCiAgICAgICAgICAgICAgICAvL1JFUVVJUkVTIHRoZSBmdW5jdGlvbiB0byBleHBlY3QgdGhlIENvbW1vbkpTIHZhcmlhYmxlcyBpbiB0aGUKICAgICAgICAgICAgICAgIC8vb3JkZXIgbGlzdGVkIGJlbG93LgogICAgICAgICAgICAgICAgZGVwcyA9IChjYWxsYmFjay5sZW5ndGggPT09IDEgPyBbJ3JlcXVpcmUnXSA6IFsncmVxdWlyZScsICdleHBvcnRzJywgJ21vZHVsZSddKS5jb25jYXQoZGVwcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vSWYgaW4gSUUgNi04IGFuZCBoaXQgYW4gYW5vbnltb3VzIGRlZmluZSgpIGNhbGwsIGRvIHRoZSBpbnRlcmFjdGl2ZQogICAgICAgIC8vd29yay4KICAgICAgICBpZiAodXNlSW50ZXJhY3RpdmUpIHsKICAgICAgICAgICAgbm9kZSA9IGN1cnJlbnRseUFkZGluZ1NjcmlwdCB8fCBnZXRJbnRlcmFjdGl2ZVNjcmlwdCgpOwogICAgICAgICAgICBpZiAobm9kZSkgewogICAgICAgICAgICAgICAgaWYgKCFuYW1lKSB7CiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IG5vZGUuZ2V0QXR0cmlidXRlKCdkYXRhLXJlcXVpcmVtb2R1bGUnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRleHQgPSBjb250ZXh0c1tub2RlLmdldEF0dHJpYnV0ZSgnZGF0YS1yZXF1aXJlY29udGV4dCcpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9BbHdheXMgc2F2ZSBvZmYgZXZhbHVhdGluZyB0aGUgZGVmIGNhbGwgdW50aWwgdGhlIHNjcmlwdCBvbmxvYWQgaGFuZGxlci4KICAgICAgICAvL1RoaXMgYWxsb3dzIG11bHRpcGxlIG1vZHVsZXMgdG8gYmUgaW4gYSBmaWxlIHdpdGhvdXQgcHJlbWF0dXJlbHkKICAgICAgICAvL3RyYWNpbmcgZGVwZW5kZW5jaWVzLCBhbmQgYWxsb3dzIGZvciBhbm9ueW1vdXMgbW9kdWxlIHN1cHBvcnQsCiAgICAgICAgLy93aGVyZSB0aGUgbW9kdWxlIG5hbWUgaXMgbm90IGtub3duIHVudGlsIHRoZSBzY3JpcHQgb25sb2FkIGV2ZW50CiAgICAgICAgLy9vY2N1cnMuIElmIG5vIGNvbnRleHQsIHVzZSB0aGUgZ2xvYmFsIHF1ZXVlLCBhbmQgZ2V0IGl0IHByb2Nlc3NlZAogICAgICAgIC8vaW4gdGhlIG9uc2NyaXB0IGxvYWQgY2FsbGJhY2suCiAgICAgICAgaWYgKGNvbnRleHQpIHsKICAgICAgICAgICAgY29udGV4dC5kZWZRdWV1ZS5wdXNoKFtuYW1lLCBkZXBzLCBjYWxsYmFja10pOwogICAgICAgICAgICBjb250ZXh0LmRlZlF1ZXVlTWFwW25hbWVdID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbG9iYWxEZWZRdWV1ZS5wdXNoKFtuYW1lLCBkZXBzLCBjYWxsYmFja10pOwogICAgICAgIH0KICAgIH07CgogICAgZGVmaW5lLmFtZCA9IHsKICAgICAgICBqUXVlcnk6IHRydWUKICAgIH07CgogICAgLyoqCiAgICAgKiBFeGVjdXRlcyB0aGUgdGV4dC4gTm9ybWFsbHkganVzdCB1c2VzIGV2YWwsIGJ1dCBjYW4gYmUgbW9kaWZpZWQKICAgICAqIHRvIHVzZSBhIGJldHRlciwgZW52aXJvbm1lbnQtc3BlY2lmaWMgY2FsbC4gT25seSB1c2VkIGZvciB0cmFuc3BpbGluZwogICAgICogbG9hZGVyIHBsdWdpbnMsIG5vdCBmb3IgcGxhaW4gSlMgbW9kdWxlcy4KICAgICAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0IHRoZSB0ZXh0IHRvIGV4ZWN1dGUvZXZhbHVhdGUuCiAgICAgKi8KICAgIHJlcS5leGVjID0gZnVuY3Rpb24gKHRleHQpIHsKICAgICAgICAvKmpzbGludCBldmlsOiB0cnVlICovCiAgICAgICAgcmV0dXJuIGV2YWwodGV4dCk7CiAgICB9OwoKICAgIC8vU2V0IHVwIHdpdGggY29uZmlnIGluZm8uCiAgICByZXEoY2ZnKTsKfSh0aGlzKSk7Cg==", - "ok": true, - "headers": [ - [ - "content-type", - "application/javascript" - ] - ], - "status": 200, - "status_text": "" - } - }, - "base_uri": "https://localhost:8080/", - "height": 835 - } + "colab": {} }, "source": [ "inp_text = to_tokens(vien_encoders[\"inputs\"].encode(inputs), hparams)\n", @@ -974,447 +608,7 @@ "attention.show(inp_text, out_text, enc_atts, dec_atts_revised, encdec_atts_revised)" ], "execution_count": 0, - "outputs": [ - { - "output_type": "display_data", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "\n", - " \n", - " \n", - " " - ] - }, - "metadata": { - "tags": [] - } - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "\n", - " \n", - " Layer: \n", - " Attention: \n", - " \n", - "
\n" - ] - }, - "metadata": { - "tags": [] - } - }, - { - "output_type": "display_data", - "data": { - "application/javascript": [ - "window.attention = {\"inp_out\": {\"top_text\": [\"T\\u00f4i_\", \"l\\u00e0_\", \"m\\u1ed9t_\", \"th\\u1ea7y_\", \"gi\\u00e1o_\", \"gi\\u1ecfi_\"], \"att\": [[[[0.8704420924186707, 0.016848094761371613, 0.06535697728395462, 0.008488952182233334, 0.0037803861778229475, 0.02092915028333664, 0.014154374599456787], [0.020669246092438698, 0.8508179187774658, 0.055849745869636536, 0.0038667197804898024, 0.006310362368822098, 0.021960174664855003, 0.040525712072849274], [0.1735430657863617, 0.32477521896362305, 0.13954930007457733, 0.02179960533976555, 0.04754350706934929, 0.09125582873821259, 0.20153342187404633], [0.06143941730260849, 0.20006392896175385, 0.1802016645669937, 0.01735481433570385, 0.03391524404287338, 0.05859356373548508, 0.44843146204948425], [0.2786475718021393, 0.09956865012645721, 0.1830715537071228, 0.00796116329729557, 0.01797572150826454, 0.055990949273109436, 0.3567843735218048], [0.006937320344150066, 0.017458226531744003, 0.4584676921367645, 0.05992313101887703, 0.04528820514678955, 0.32295477390289307, 0.0889706239104271], [0.0016268318286165595, 0.0010809615487232804, 0.022502580657601357, 0.22151270508766174, 0.10862091928720474, 0.6404592990875244, 0.004196654539555311], [0.0040534730069339275, 0.0017439823132008314, 0.02856196090579033, 0.4200330972671509, 0.23108617961406708, 0.2855648696422577, 0.028956424444913864], [0.02295745722949505, 0.049420394003391266, 0.06168053299188614, 0.018957268446683884, 0.01692030392587185, 0.04323732852935791, 0.7868266701698303], [0.08846691995859146, 0.034101326018571854, 0.058807745575904846, 0.12842193245887756, 0.13569492101669312, 0.21415281295776367, 0.3403543531894684]], [[0.9099982976913452, 0.016881326213479042, 0.025195995345711708, 0.0067000845447182655, 0.006413946393877268, 0.0184308048337698, 0.0163797028362751], [0.09182468056678772, 0.7740237712860107, 0.09606373310089111, 0.003224016400054097, 0.0036482010036706924, 0.013215611688792706, 0.018000014126300812], [0.30276718735694885, 0.41830870509147644, 0.16967947781085968, 0.009733201004564762, 0.011700917966663837, 0.07193415611982346, 0.015876298770308495], [0.38737332820892334, 0.09481148421764374, 0.17309065163135529, 0.004311066120862961, 0.01619401015341282, 0.11244773864746094, 0.21177174150943756], [0.05892055481672287, 0.8017334342002869, 0.09872456640005112, 0.0008841324015520513, 0.0022817139979451895, 0.023263661190867424, 0.014191905967891216], [0.0014801048673689365, 0.9429510831832886, 0.0514342300593853, 9.78592288447544e-05, 0.00018731066666077822, 0.0037232120521366596, 0.00012627757678274065], [0.00581245357170701, 0.0033489582128822803, 0.1021064817905426, 0.6926131844520569, 0.10790067166090012, 0.08467500656843185, 0.003543251659721136], [0.05634903162717819, 0.0008741982164792717, 0.010385713540017605, 0.10904653370380402, 0.08750903606414795, 0.5385743379592896, 0.19726109504699707], [0.026357118040323257, 0.002158109564334154, 0.005419131368398666, 0.0027515790425240993, 0.004469003994017839, 0.10696206986904144, 0.851883053779602], [0.013084910809993744, 0.014081600122153759, 0.02135598286986351, 0.11089644581079483, 0.11222057789564133, 0.11983823031187057, 0.6085222959518433]], [[0.17027132213115692, 0.05881655588746071, 0.10405509918928146, 0.03283005580306053, 0.029793279245495796, 0.0316041074693203, 0.5726295709609985], [0.9067059755325317, 0.019408103078603745, 0.011975049041211605, 0.004894631449133158, 0.0027939907740801573, 0.0017228084616363049, 0.05249936878681183], [0.1533142626285553, 0.517569899559021, 0.14652903378009796, 0.009476382285356522, 0.005730700213462114, 0.01592874899506569, 0.15145094692707062], [0.12722541391849518, 0.26932796835899353, 0.19737444818019867, 0.007304077502340078, 0.0031481324695050716, 0.04731717333197594, 0.3483027219772339], [0.4550265967845917, 0.14376334846019745, 0.11472027003765106, 0.018293162807822227, 0.011069105006754398, 0.014812084846198559, 0.24231545627117157], [0.08904443681240082, 0.7540519833564758, 0.11339341849088669, 0.008039996027946472, 0.004379874095320702, 0.005316981580108404, 0.025773270055651665], [0.022439071908593178, 0.15722057223320007, 0.7313699126243591, 0.006610111333429813, 0.00376239325851202, 0.021182797849178314, 0.05741505324840546], [0.0027674713637679815, 0.008739779703319073, 0.06316893547773361, 0.004738922230899334, 0.0066871969029307365, 0.8879024982452393, 0.02599521167576313], [0.004636347759515047, 0.0017214042600244284, 0.02422073669731617, 0.5704393982887268, 0.38708263635635376, 0.009022869169712067, 0.002876587910577655], [0.06856774538755417, 0.04091061279177666, 0.06274397671222687, 0.09936398267745972, 0.06197868287563324, 0.11424196511507034, 0.5521929860115051]], [[0.3554643392562866, 0.14491558074951172, 0.07180142402648926, 0.052635032683610916, 0.049085795879364014, 0.1259079873561859, 0.20018982887268066], [0.10243949294090271, 0.18617737293243408, 0.1826625019311905, 0.047409359365701675, 0.02488633245229721, 0.12387506663799286, 0.33254989981651306], [0.29309549927711487, 0.18865610659122467, 0.2421494871377945, 0.025121739134192467, 0.02436918020248413, 0.0785471647977829, 0.14806078374385834], [0.26852792501449585, 0.1573915332555771, 0.2851622402667999, 0.03977484256029129, 0.030091112479567528, 0.05491195619106293, 0.16414031386375427], [0.164560005068779, 0.21444012224674225, 0.22567813098430634, 0.04420643299818039, 0.04604777321219444, 0.0859815925359726, 0.21908588707447052], [0.1100199744105339, 0.24695546925067902, 0.21828147768974304, 0.046465836465358734, 0.07045458257198334, 0.18237604200839996, 0.12544669210910797], [0.07192080467939377, 0.06293681263923645, 0.061889197677373886, 0.03514832258224487, 0.06326429545879364, 0.6223936080932617, 0.08244694769382477], [0.07811861485242844, 0.04360093176364899, 0.14392557740211487, 0.1380978226661682, 0.13988730311393738, 0.2455078661441803, 0.21086184680461884], [0.1860654652118683, 0.038002509623765945, 0.10534133017063141, 0.05035144463181496, 0.038954026997089386, 0.11098027974367142, 0.4703048765659332], [0.05538519099354744, 0.07076521962881088, 0.09005095064640045, 0.18425409495830536, 0.15123078227043152, 0.2699128985404968, 0.17840082943439484]]], [[[0.9214363098144531, 0.03383532911539078, 0.01264380943030119, 0.003529202425852418, 0.0034334694501012564, 0.012241607531905174, 0.01288024615496397], [0.024965152144432068, 0.9234139323234558, 0.03535483777523041, 0.0009384001605212688, 0.0015650022542104125, 0.01226071733981371, 0.0015019557904452085], [0.6153647899627686, 0.13977935910224915, 0.04471490532159805, 0.030891740694642067, 0.04217227175831795, 0.0957980677485466, 0.031278956681489944], [0.41005077958106995, 0.11048655211925507, 0.07939636707305908, 0.10599720478057861, 0.07617311924695969, 0.13233989477157593, 0.08555607497692108], [0.19289293885231018, 0.7381836175918579, 0.04198357090353966, 0.00262664956972003, 0.00506624998524785, 0.017658619210124016, 0.0015884079039096832], [0.016352981328964233, 0.06788863986730576, 0.8628089427947998, 0.013561571948230267, 0.007813890464603901, 0.02971986122429371, 0.0018540103919804096], [0.0053925178945064545, 0.008957717567682266, 0.03927428275346756, 0.18735632300376892, 0.11030028760433197, 0.6422249674797058, 0.006493907887488604], [0.0008184831240214407, 0.00017204518371727318, 0.006272793281823397, 0.6783341765403748, 0.1468169242143631, 0.16273802518844604, 0.004847539588809013], [0.015248088166117668, 0.0007294111419469118, 0.0038423652295023203, 0.009012322872877121, 0.009222744964063168, 0.1259298473596573, 0.8360152840614319], [0.2476823925971985, 0.049524471163749695, 0.03487221896648407, 0.09451624006032944, 0.08944175392389297, 0.13350023329257965, 0.35046276450157166]], [[0.6725015640258789, 0.14312002062797546, 0.08035705238580704, 0.007104868069291115, 0.00882151909172535, 0.042893167585134506, 0.0452018678188324], [0.021230019629001617, 0.6777331233024597, 0.05629396066069603, 0.007317465264350176, 0.006615524645894766, 0.056344542652368546, 0.17446525394916534], [0.002255259780213237, 0.0003727954172063619, 9.186741226585582e-05, 3.395611565792933e-05, 4.90796628582757e-05, 9.304583363700658e-05, 0.9971039891242981], [0.0008421869715675712, 0.00034091208362951875, 0.00012069622607668862, 9.29130328586325e-05, 0.0001406583614880219, 0.00016517259064130485, 0.9982975125312805], [0.005186453927308321, 0.003334906417876482, 0.0011353034060448408, 0.0001702228473732248, 0.00019168351718690246, 0.000844618072733283, 0.989136815071106], [0.022418180480599403, 0.1259237825870514, 0.354306697845459, 0.03597964718937874, 0.03806745260953903, 0.38585272431373596, 0.03745153918862343], [0.0066866399720311165, 0.006022755987942219, 0.03101474978029728, 0.08936619013547897, 0.10349436849355698, 0.7327824234962463, 0.03063281439244747], [0.00480573670938611, 0.0032871344592422247, 0.02849743515253067, 0.5222172737121582, 0.32273945212364197, 0.10450031608343124, 0.013952699489891529], [0.16481062769889832, 0.23238521814346313, 0.11912276595830917, 0.08460792154073715, 0.0341351218521595, 0.1491413414478302, 0.21579709649085999], [0.02422461472451687, 0.002847088035196066, 0.0009453023667447269, 0.0006329436437226832, 0.0008360451320186257, 0.0017606281908228993, 0.9687533974647522]], [[0.6485046148300171, 0.06104779615998268, 0.0987863540649414, 0.015504126437008381, 0.014928942546248436, 0.055928975343704224, 0.10529918223619461], [0.08062625676393509, 0.5489323735237122, 0.17290839552879333, 0.013752092607319355, 0.014732828363776207, 0.03315730765461922, 0.13589082658290863], [0.037759024649858475, 0.016137996688485146, 0.004731189925223589, 0.0006356077501550317, 0.0006547167431563139, 0.0011489748721942306, 0.9389325380325317], [0.014034979976713657, 0.015085851773619652, 0.006108575966209173, 0.0013066098326817155, 0.0010462956270202994, 0.0018550031818449497, 0.9605626463890076], [0.13421647250652313, 0.29931968450546265, 0.10111778974533081, 0.0021840825211256742, 0.002359112026169896, 0.004506533499807119, 0.4562963545322418], [0.054040152579545975, 0.0783623605966568, 0.19096656143665314, 0.0852397009730339, 0.09076802432537079, 0.46771734952926636, 0.0329059474170208], [0.00946064107120037, 0.0050847637467086315, 0.02243950217962265, 0.049588583409786224, 0.0746847614645958, 0.8247678279876709, 0.01397393736988306], [0.006637475453317165, 0.001469822833314538, 0.024216588586568832, 0.4852747619152069, 0.30718183517456055, 0.16875219345092773, 0.00646736565977335], [0.08290112763643265, 0.011326649226248264, 0.02782600000500679, 0.04411173611879349, 0.023406144231557846, 0.024495743215084076, 0.7859325408935547], [0.03634504973888397, 0.009904504753649235, 0.006170039996504784, 0.002310507232323289, 0.002003848785534501, 0.004329503979533911, 0.9389365315437317]], [[0.7204623818397522, 0.15079210698604584, 0.05447116494178772, 0.006460077129304409, 0.006790574174374342, 0.032226163893938065, 0.028797516599297523], [0.1317957043647766, 0.44598543643951416, 0.15875999629497528, 0.036555420607328415, 0.04254429414868355, 0.11798373609781265, 0.06637534499168396], [0.5291085839271545, 0.24166184663772583, 0.030280351638793945, 0.005381480790674686, 0.009701697155833244, 0.017125453799962997, 0.1667405068874359], [0.34981054067611694, 0.24570712447166443, 0.04219246655702591, 0.01731989160180092, 0.031316399574279785, 0.02935669757425785, 0.2842968702316284], [0.20586538314819336, 0.6520161032676697, 0.06506667286157608, 0.004951995797455311, 0.012885564006865025, 0.02985270880162716, 0.02936149388551712], [0.02233482152223587, 0.013396072201430798, 0.2521381676197052, 0.053246449679136276, 0.02902820333838463, 0.6213862299919128, 0.008470054715871811], [0.00811708439141512, 0.0028292203787714243, 0.014457887038588524, 0.035222675651311874, 0.04888743534684181, 0.8825169801712036, 0.007968656718730927], [0.0064574419520795345, 0.0010605924762785435, 0.01621074043214321, 0.594968318939209, 0.19993533194065094, 0.16750384867191315, 0.013863756321370602], [0.08108135312795639, 0.024279514327645302, 0.08674605935811996, 0.04651370644569397, 0.025959884747862816, 0.05356903001666069, 0.6818504333496094], [0.15945376455783844, 0.11512232571840286, 0.03884574770927429, 0.01973307691514492, 0.03261934593319893, 0.05912620946764946, 0.5750994682312012]]]], \"bot_text\": [\"I_\", \" &_\", \"apos_\", \";_\", \"m_\", \"a_\", \"good_\", \"teacher_\", \" ._\"]}, \"all\": {\"top_text\": [\"T\\u00f4i_\", \"l\\u00e0_\", \"m\\u1ed9t_\", \"th\\u1ea7y_\", \"gi\\u00e1o_\", \"gi\\u1ecfi_\", \"I_\", \" &_\", \"apos_\", \";_\", \"m_\", \"a_\", \"good_\", \"teacher_\", \" ._\"], \"att\": [[[[0.15637657046318054, 0.031179480254650116, 0.0591559112071991, 0.03467392176389694, 0.01973690837621689, 0.06068029627203941, 0.6381968855857849, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.24990732967853546, 0.04834190756082535, 0.16599032282829285, 0.08423759043216705, 0.04652909189462662, 0.08058451116085052, 0.32440927624702454, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.010967226698994637, 0.02172553725540638, 0.03470718488097191, 0.14958412945270538, 0.23588316142559052, 0.5219144225120544, 0.025218378752470016, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0061057014390826225, 0.0021930125076323748, 0.010520044714212418, 0.215690478682518, 0.4664883017539978, 0.23077654838562012, 0.06822594255208969, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.004976624622941017, 0.0006474226247519255, 0.0038635318633168936, 0.4096323549747467, 0.13856898248195648, 0.38877660036087036, 0.05353453755378723, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0020405075047165155, 0.000558990694116801, 0.002208310877904296, 0.010428190231323242, 0.05572662502527237, 0.09833728522062302, 0.8307000994682312, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.04859629273414612, 0.0992843508720398, 0.024837173521518707, 0.022672463208436966, 0.041493821889162064, 0.10241886973381042, 0.6606969833374023, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.8704420924186707, 0.016848094761371613, 0.06535697728395462, 0.008488952182233334, 0.0037803861778229475, 0.02092915028333664, 0.014154374599456787, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.020669246092438698, 0.8508179187774658, 0.055849745869636536, 0.0038667197804898024, 0.006310362368822098, 0.021960174664855003, 0.040525712072849274, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.1735430657863617, 0.32477521896362305, 0.13954930007457733, 0.02179960533976555, 0.04754350706934929, 0.09125582873821259, 0.20153342187404633, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.06143941730260849, 0.20006392896175385, 0.1802016645669937, 0.01735481433570385, 0.03391524404287338, 0.05859356373548508, 0.44843146204948425, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.2786475718021393, 0.09956865012645721, 0.1830715537071228, 0.00796116329729557, 0.01797572150826454, 0.055990949273109436, 0.3567843735218048, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.006937320344150066, 0.017458226531744003, 0.4584676921367645, 0.05992313101887703, 0.04528820514678955, 0.32295477390289307, 0.0889706239104271, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0016268318286165595, 0.0010809615487232804, 0.022502580657601357, 0.22151270508766174, 0.10862091928720474, 0.6404592990875244, 0.004196654539555311, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0040534730069339275, 0.0017439823132008314, 0.02856196090579033, 0.4200330972671509, 0.23108617961406708, 0.2855648696422577, 0.028956424444913864, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.02295745722949505, 0.049420394003391266, 0.06168053299188614, 0.018957268446683884, 0.01692030392587185, 0.04323732852935791, 0.7868266701698303, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.08846691995859146, 0.034101326018571854, 0.058807745575904846, 0.12842193245887756, 0.13569492101669312, 0.21415281295776367, 0.3403543531894684, 0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512]], [[0.08919383585453033, 0.5788573622703552, 0.2900116443634033, 0.00536323431879282, 0.0054911295883357525, 0.010270982049405575, 0.020811777561903, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.05315522477030754, 0.05477380007505417, 0.7107505202293396, 0.07555636018514633, 0.044316332787275314, 0.0329383946955204, 0.028509408235549927, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.004811703693121672, 0.05610184371471405, 0.023363150656223297, 0.04314766079187393, 0.19077634811401367, 0.451174259185791, 0.23062501847743988, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.01629498414695263, 0.008990052156150341, 0.016501707956194878, 0.003588054794818163, 0.04053742438554764, 0.10115395486354828, 0.8129338026046753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0022456306032836437, 0.002136725466698408, 0.0011441110400483012, 0.00033694354351609945, 0.00807734951376915, 0.06298699975013733, 0.9230722188949585, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.025586603209376335, 0.008633822202682495, 0.004241446498781443, 0.0016273887595161796, 0.012170940637588501, 0.049063485115766525, 0.898676335811615, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.03341146558523178, 0.02379998005926609, 0.010208996944129467, 0.002263963920995593, 0.006787281483411789, 0.0869273841381073, 0.8366009593009949, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.9099982976913452, 0.016881326213479042, 0.025195995345711708, 0.0067000845447182655, 0.006413946393877268, 0.0184308048337698, 0.0163797028362751, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.09182468056678772, 0.7740237712860107, 0.09606373310089111, 0.003224016400054097, 0.0036482010036706924, 0.013215611688792706, 0.018000014126300812, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.30276718735694885, 0.41830870509147644, 0.16967947781085968, 0.009733201004564762, 0.011700917966663837, 0.07193415611982346, 0.015876298770308495, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.38737332820892334, 0.09481148421764374, 0.17309065163135529, 0.004311066120862961, 0.01619401015341282, 0.11244773864746094, 0.21177174150943756, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.05892055481672287, 0.8017334342002869, 0.09872456640005112, 0.0008841324015520513, 0.0022817139979451895, 0.023263661190867424, 0.014191905967891216, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.0014801048673689365, 0.9429510831832886, 0.0514342300593853, 9.78592288447544e-05, 0.00018731066666077822, 0.0037232120521366596, 0.00012627757678274065, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00581245357170701, 0.0033489582128822803, 0.1021064817905426, 0.6926131844520569, 0.10790067166090012, 0.08467500656843185, 0.003543251659721136, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.05634903162717819, 0.0008741982164792717, 0.010385713540017605, 0.10904653370380402, 0.08750903606414795, 0.5385743379592896, 0.19726109504699707, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.026357118040323257, 0.002158109564334154, 0.005419131368398666, 0.0027515790425240993, 0.004469003994017839, 0.10696206986904144, 0.851883053779602, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.013084910809993744, 0.014081600122153759, 0.02135598286986351, 0.11089644581079483, 0.11222057789564133, 0.11983823031187057, 0.6085222959518433, 0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512]], [[0.1794050633907318, 0.10620228201150894, 0.08233162015676498, 0.12294647097587585, 0.03687690570950508, 0.06893271207809448, 0.40330493450164795, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.39334648847579956, 0.026603734120726585, 0.30390098690986633, 0.012356402352452278, 0.0041913981549441814, 0.03003511391580105, 0.22956588864326477, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.027390550822019577, 0.16503988206386566, 0.04586160555481911, 0.2302263230085373, 0.13011474907398224, 0.29631760716438293, 0.10504936426877975, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.005118991248309612, 0.005646487697958946, 0.012889642268419266, 0.46222004294395447, 0.26949939131736755, 0.07023416459560394, 0.17439128458499908, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.004886195063591003, 0.0028036495205014944, 0.016034258529543877, 0.4406549036502838, 0.09583024680614471, 0.15249089896678925, 0.28729987144470215, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.009601201862096786, 0.0009394164080731571, 0.014605253003537655, 0.05758216604590416, 0.1045263409614563, 0.16328158974647522, 0.6494640111923218, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0011346392566338181, 0.00190354126971215, 0.0005144121241755784, 0.0032229411881417036, 0.0033254751469939947, 0.05584224686026573, 0.9340567588806152, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.17027132213115692, 0.05881655588746071, 0.10405509918928146, 0.03283005580306053, 0.029793279245495796, 0.0316041074693203, 0.5726295709609985, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.9067059755325317, 0.019408103078603745, 0.011975049041211605, 0.004894631449133158, 0.0027939907740801573, 0.0017228084616363049, 0.05249936878681183, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.1533142626285553, 0.517569899559021, 0.14652903378009796, 0.009476382285356522, 0.005730700213462114, 0.01592874899506569, 0.15145094692707062, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.12722541391849518, 0.26932796835899353, 0.19737444818019867, 0.007304077502340078, 0.0031481324695050716, 0.04731717333197594, 0.3483027219772339, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.4550265967845917, 0.14376334846019745, 0.11472027003765106, 0.018293162807822227, 0.011069105006754398, 0.014812084846198559, 0.24231545627117157, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.08904443681240082, 0.7540519833564758, 0.11339341849088669, 0.008039996027946472, 0.004379874095320702, 0.005316981580108404, 0.025773270055651665, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.022439071908593178, 0.15722057223320007, 0.7313699126243591, 0.006610111333429813, 0.00376239325851202, 0.021182797849178314, 0.05741505324840546, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.0027674713637679815, 0.008739779703319073, 0.06316893547773361, 0.004738922230899334, 0.0066871969029307365, 0.8879024982452393, 0.02599521167576313, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.004636347759515047, 0.0017214042600244284, 0.02422073669731617, 0.5704393982887268, 0.38708263635635376, 0.009022869169712067, 0.002876587910577655, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.06856774538755417, 0.04091061279177666, 0.06274397671222687, 0.09936398267745972, 0.06197868287563324, 0.11424196511507034, 0.5521929860115051, 0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633]], [[0.23925544321537018, 0.1495950073003769, 0.074134960770607, 0.13400912284851074, 0.036855194717645645, 0.20192593336105347, 0.16422437131404877, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.4463321268558502, 0.08793879300355911, 0.11290805786848068, 0.13659793138504028, 0.0393790677189827, 0.09606495499610901, 0.0807790756225586, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.22583530843257904, 0.1117587611079216, 0.11304541677236557, 0.22597678005695343, 0.07174260914325714, 0.14210860431194305, 0.10953247547149658, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.21184861660003662, 0.11912985891103745, 0.08142074197530746, 0.20865124464035034, 0.125769704580307, 0.16199974715709686, 0.09118017554283142, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.13423313200473785, 0.04413554072380066, 0.0810641422867775, 0.4767560660839081, 0.09756991267204285, 0.11681855469942093, 0.04942258074879646, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.09112156927585602, 0.1221369057893753, 0.29441726207733154, 0.15917669236660004, 0.17216818034648895, 0.1071373000741005, 0.05384201183915138, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.12218175083398819, 0.29104188084602356, 0.18802489340305328, 0.13109752535820007, 0.08446026593446732, 0.11128930002450943, 0.07190437614917755, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.3554643392562866, 0.14491558074951172, 0.07180142402648926, 0.052635032683610916, 0.049085795879364014, 0.1259079873561859, 0.20018982887268066, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.10243949294090271, 0.18617737293243408, 0.1826625019311905, 0.047409359365701675, 0.02488633245229721, 0.12387506663799286, 0.33254989981651306, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.29309549927711487, 0.18865610659122467, 0.2421494871377945, 0.025121739134192467, 0.02436918020248413, 0.0785471647977829, 0.14806078374385834, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.26852792501449585, 0.1573915332555771, 0.2851622402667999, 0.03977484256029129, 0.030091112479567528, 0.05491195619106293, 0.16414031386375427, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.164560005068779, 0.21444012224674225, 0.22567813098430634, 0.04420643299818039, 0.04604777321219444, 0.0859815925359726, 0.21908588707447052, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.1100199744105339, 0.24695546925067902, 0.21828147768974304, 0.046465836465358734, 0.07045458257198334, 0.18237604200839996, 0.12544669210910797, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.07192080467939377, 0.06293681263923645, 0.061889197677373886, 0.03514832258224487, 0.06326429545879364, 0.6223936080932617, 0.08244694769382477, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.07811861485242844, 0.04360093176364899, 0.14392557740211487, 0.1380978226661682, 0.13988730311393738, 0.2455078661441803, 0.21086184680461884, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.1860654652118683, 0.038002509623765945, 0.10534133017063141, 0.05035144463181496, 0.038954026997089386, 0.11098027974367142, 0.4703048765659332, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.05538519099354744, 0.07076521962881088, 0.09005095064640045, 0.18425409495830536, 0.15123078227043152, 0.2699128985404968, 0.17840082943439484, 0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156]]], [[[0.033222347497940063, 0.01117094699293375, 0.004438965581357479, 0.014089155942201614, 0.013568120077252388, 0.08421560376882553, 0.839294970035553, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.9909290671348572, 0.0031243504490703344, 0.0009099586750380695, 0.00044803490163758397, 0.00017059814126696438, 0.0004778687725774944, 0.00394014036282897, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.026670319959521294, 0.8587448596954346, 0.09465216100215912, 0.01478393655270338, 0.002567719668149948, 0.001430327189154923, 0.001150674419477582, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [5.5622564104851335e-05, 0.0029673262033611536, 0.9571806788444519, 0.032983843237161636, 0.004578517284244299, 0.0019641409162431955, 0.00026985432486981153, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.00016515454626642168, 0.0006547846714965999, 0.6357616186141968, 0.2341514378786087, 0.05240916088223457, 0.07244595885276794, 0.004411905072629452, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.00032206965261138976, 4.0217168134404346e-05, 0.10160578787326813, 0.24953864514827728, 0.3993138372898102, 0.1859280914068222, 0.06325137615203857, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0007896021706983447, 0.00010236073285341263, 0.0023883029352873564, 0.08584544062614441, 0.21642054617404938, 0.6267321705818176, 0.06772156059741974, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.9214363098144531, 0.03383532911539078, 0.01264380943030119, 0.003529202425852418, 0.0034334694501012564, 0.012241607531905174, 0.01288024615496397, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.024965152144432068, 0.9234139323234558, 0.03535483777523041, 0.0009384001605212688, 0.0015650022542104125, 0.01226071733981371, 0.0015019557904452085, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.6153647899627686, 0.13977935910224915, 0.04471490532159805, 0.030891740694642067, 0.04217227175831795, 0.0957980677485466, 0.031278956681489944, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.41005077958106995, 0.11048655211925507, 0.07939636707305908, 0.10599720478057861, 0.07617311924695969, 0.13233989477157593, 0.08555607497692108, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.19289293885231018, 0.7381836175918579, 0.04198357090353966, 0.00262664956972003, 0.00506624998524785, 0.017658619210124016, 0.0015884079039096832, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.016352981328964233, 0.06788863986730576, 0.8628089427947998, 0.013561571948230267, 0.007813890464603901, 0.02971986122429371, 0.0018540103919804096, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.0053925178945064545, 0.008957717567682266, 0.03927428275346756, 0.18735632300376892, 0.11030028760433197, 0.6422249674797058, 0.006493907887488604, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.0008184831240214407, 0.00017204518371727318, 0.006272793281823397, 0.6783341765403748, 0.1468169242143631, 0.16273802518844604, 0.004847539588809013, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.015248088166117668, 0.0007294111419469118, 0.0038423652295023203, 0.009012322872877121, 0.009222744964063168, 0.1259298473596573, 0.8360152840614319, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.2476823925971985, 0.049524471163749695, 0.03487221896648407, 0.09451624006032944, 0.08944175392389297, 0.13350023329257965, 0.35046276450157166, 0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653]], [[0.013507821597158909, 0.003428569296374917, 0.0005854362389072776, 0.0008416551863774657, 0.0004880995547864586, 0.0008058223174884915, 0.9803426265716553, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.822248637676239, 0.04045531526207924, 0.01175216119736433, 0.0021381382830441, 0.0019350502407178283, 0.003611659398302436, 0.11785909533500671, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.15152117609977722, 0.685112476348877, 0.14481458067893982, 0.00551303057000041, 0.0018123624613508582, 0.002342620864510536, 0.008883670903742313, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.010127967223525047, 0.18935945630073547, 0.777565062046051, 0.005309808999300003, 0.002551265060901642, 0.009146109223365784, 0.005940355826169252, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.008314592763781548, 0.0869276374578476, 0.83534836769104, 0.011873320676386356, 0.008547228761017323, 0.041367579251527786, 0.007621485739946365, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.007179880980402231, 0.013340642675757408, 0.8176888227462769, 0.021866271272301674, 0.03257835656404495, 0.06856315582990646, 0.03878301754593849, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.001468008616939187, 0.00106660439632833, 0.030770542100071907, 0.06526954472064972, 0.15483789145946503, 0.7391741275787354, 0.007413213141262531, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.6725015640258789, 0.14312002062797546, 0.08035705238580704, 0.007104868069291115, 0.00882151909172535, 0.042893167585134506, 0.0452018678188324, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.021230019629001617, 0.6777331233024597, 0.05629396066069603, 0.007317465264350176, 0.006615524645894766, 0.056344542652368546, 0.17446525394916534, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.002255259780213237, 0.0003727954172063619, 9.186741226585582e-05, 3.395611565792933e-05, 4.90796628582757e-05, 9.304583363700658e-05, 0.9971039891242981, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.0008421869715675712, 0.00034091208362951875, 0.00012069622607668862, 9.29130328586325e-05, 0.0001406583614880219, 0.00016517259064130485, 0.9982975125312805, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.005186453927308321, 0.003334906417876482, 0.0011353034060448408, 0.0001702228473732248, 0.00019168351718690246, 0.000844618072733283, 0.989136815071106, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.022418180480599403, 0.1259237825870514, 0.354306697845459, 0.03597964718937874, 0.03806745260953903, 0.38585272431373596, 0.03745153918862343, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.0066866399720311165, 0.006022755987942219, 0.03101474978029728, 0.08936619013547897, 0.10349436849355698, 0.7327824234962463, 0.03063281439244747, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.00480573670938611, 0.0032871344592422247, 0.02849743515253067, 0.5222172737121582, 0.32273945212364197, 0.10450031608343124, 0.013952699489891529, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.16481062769889832, 0.23238521814346313, 0.11912276595830917, 0.08460792154073715, 0.0341351218521595, 0.1491413414478302, 0.21579709649085999, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.02422461472451687, 0.002847088035196066, 0.0009453023667447269, 0.0006329436437226832, 0.0008360451320186257, 0.0017606281908228993, 0.9687533974647522, 0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364]], [[0.24491305649280548, 0.2716386020183563, 0.2974568009376526, 0.0715150237083435, 0.032737474888563156, 0.03313692659139633, 0.048602212220430374, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.06463561207056046, 0.0433550626039505, 0.5164699554443359, 0.2553751766681671, 0.05558573082089424, 0.03877051919698715, 0.02580798976123333, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.005344105418771505, 0.004306877497583628, 0.02483231946825981, 0.35550329089164734, 0.18227519094944, 0.35200417041778564, 0.07573401182889938, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.002322714775800705, 0.001051871688105166, 0.025118347257375717, 0.03140588477253914, 0.10554895550012589, 0.6380510926246643, 0.19650113582611084, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0009995860746130347, 0.0004442579811438918, 0.0043803914450109005, 0.010685287415981293, 0.04103739187121391, 0.6786168217658997, 0.2638362944126129, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.006038180086761713, 0.0021745343692600727, 0.006020124536007643, 0.011885320767760277, 0.07246774435043335, 0.3011493384838104, 0.6002647280693054, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.14067502319812775, 0.06330223381519318, 0.04618984833359718, 0.025883490219712257, 0.09871792048215866, 0.17052823305130005, 0.45470327138900757, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.6485046148300171, 0.06104779615998268, 0.0987863540649414, 0.015504126437008381, 0.014928942546248436, 0.055928975343704224, 0.10529918223619461, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.08062625676393509, 0.5489323735237122, 0.17290839552879333, 0.013752092607319355, 0.014732828363776207, 0.03315730765461922, 0.13589082658290863, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.037759024649858475, 0.016137996688485146, 0.004731189925223589, 0.0006356077501550317, 0.0006547167431563139, 0.0011489748721942306, 0.9389325380325317, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.014034979976713657, 0.015085851773619652, 0.006108575966209173, 0.0013066098326817155, 0.0010462956270202994, 0.0018550031818449497, 0.9605626463890076, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.13421647250652313, 0.29931968450546265, 0.10111778974533081, 0.0021840825211256742, 0.002359112026169896, 0.004506533499807119, 0.4562963545322418, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.054040152579545975, 0.0783623605966568, 0.19096656143665314, 0.0852397009730339, 0.09076802432537079, 0.46771734952926636, 0.0329059474170208, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00946064107120037, 0.0050847637467086315, 0.02243950217962265, 0.049588583409786224, 0.0746847614645958, 0.8247678279876709, 0.01397393736988306, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.006637475453317165, 0.001469822833314538, 0.024216588586568832, 0.4852747619152069, 0.30718183517456055, 0.16875219345092773, 0.00646736565977335, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.08290112763643265, 0.011326649226248264, 0.02782600000500679, 0.04411173611879349, 0.023406144231557846, 0.024495743215084076, 0.7859325408935547, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.03634504973888397, 0.009904504753649235, 0.006170039996504784, 0.002310507232323289, 0.002003848785534501, 0.004329503979533911, 0.9389365315437317, 0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754]], [[0.10726487636566162, 0.040105823427438736, 0.03365788608789444, 0.05795503780245781, 0.02877318300306797, 0.06775611639022827, 0.6644870638847351, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.16149355471134186, 0.0507226437330246, 0.043050073087215424, 0.04469142109155655, 0.04235309362411499, 0.04066084325313568, 0.6170283555984497, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.34940773248672485, 0.09805944561958313, 0.0713985413312912, 0.056111957877874374, 0.03563306853175163, 0.04191041365265846, 0.34747880697250366, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.3118698298931122, 0.2712187170982361, 0.11745087802410126, 0.032837074249982834, 0.015879064798355103, 0.04398801550269127, 0.20675639808177948, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.2673729360103607, 0.26532304286956787, 0.209498792886734, 0.034180257469415665, 0.013117877766489983, 0.045311469584703445, 0.16519568860530853, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.09899894893169403, 0.24890649318695068, 0.2992298901081085, 0.06689880788326263, 0.04724286496639252, 0.05928840488195419, 0.1794346570968628, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.20271816849708557, 0.14796458184719086, 0.23876041173934937, 0.08937732130289078, 0.07028388977050781, 0.09505382925271988, 0.15584181249141693, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.7204623818397522, 0.15079210698604584, 0.05447116494178772, 0.006460077129304409, 0.006790574174374342, 0.032226163893938065, 0.028797516599297523, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1317957043647766, 0.44598543643951416, 0.15875999629497528, 0.036555420607328415, 0.04254429414868355, 0.11798373609781265, 0.06637534499168396, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.5291085839271545, 0.24166184663772583, 0.030280351638793945, 0.005381480790674686, 0.009701697155833244, 0.017125453799962997, 0.1667405068874359, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.34981054067611694, 0.24570712447166443, 0.04219246655702591, 0.01731989160180092, 0.031316399574279785, 0.02935669757425785, 0.2842968702316284, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.20586538314819336, 0.6520161032676697, 0.06506667286157608, 0.004951995797455311, 0.012885564006865025, 0.02985270880162716, 0.02936149388551712, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.02233482152223587, 0.013396072201430798, 0.2521381676197052, 0.053246449679136276, 0.02902820333838463, 0.6213862299919128, 0.008470054715871811, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.00811708439141512, 0.0028292203787714243, 0.014457887038588524, 0.035222675651311874, 0.04888743534684181, 0.8825169801712036, 0.007968656718730927, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.0064574419520795345, 0.0010605924762785435, 0.01621074043214321, 0.594968318939209, 0.19993533194065094, 0.16750384867191315, 0.013863756321370602, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.08108135312795639, 0.024279514327645302, 0.08674605935811996, 0.04651370644569397, 0.025959884747862816, 0.05356903001666069, 0.6818504333496094, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.15945376455783844, 0.11512232571840286, 0.03884574770927429, 0.01973307691514492, 0.03261934593319893, 0.05912620946764946, 0.5750994682312012, 0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527]]]], \"bot_text\": [\"T\\u00f4i_\", \"l\\u00e0_\", \"m\\u1ed9t_\", \"th\\u1ea7y_\", \"gi\\u00e1o_\", \"gi\\u1ecfi_\", \"I_\", \" &_\", \"apos_\", \";_\", \"m_\", \"a_\", \"good_\", \"teacher_\", \" ._\"]}, \"out_out\": {\"top_text\": [\"I_\", \" &_\", \"apos_\", \";_\", \"m_\", \"a_\", \"good_\", \"teacher_\", \" ._\"], \"att\": [[[[0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512], [0.0115597452968359, 0.010746532119810581, 0.01449540164321661, 0.0036987140774726868, 0.0021777665242552757, 0.00396158080548048, 0.004763186443597078, 0.0042021325789391994, 0.004610443953424692, 0.9397845268249512]], [[0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512], [0.00045425965799950063, 0.03457964211702347, 0.003488552523776889, 0.0038781273178756237, 0.0011129409540444613, 0.0286484993994236, 0.0082186758518219, 0.01982228085398674, 0.039602380245923996, 0.8601946830749512]], [[0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633], [0.10837815701961517, 0.03925019130110741, 0.008634197525680065, 0.017755866050720215, 0.011322992853820324, 0.021678278222680092, 0.015610774047672749, 0.05834418907761574, 0.3088621199131012, 0.41016319394111633]], [[0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156], [0.010170185938477516, 0.014008786529302597, 0.00595884071663022, 0.0028759846463799477, 0.003439522348344326, 0.008366807363927364, 0.0019441641634330153, 0.006025348324328661, 0.016237301751971245, 0.9309730529785156]]], [[[0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653], [0.05545441061258316, 0.17012803256511688, 0.014577098190784454, 0.016823135316371918, 0.013133577071130276, 0.13420499861240387, 0.1100165843963623, 0.11698570102453232, 0.3167814314365387, 0.05189506709575653]], [[0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364], [0.038457270711660385, 0.3145657479763031, 0.06977839022874832, 0.02983863279223442, 0.0007308990461751819, 0.03513738140463829, 0.02370334044098854, 0.08796472102403641, 0.07626271992921829, 0.3235609233379364]], [[0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754], [0.00239205127581954, 0.0004023782385047525, 0.08562200516462326, 0.12396063655614853, 0.0006014585378579795, 0.0016860963078215718, 0.0018407071474939585, 0.0029011336155235767, 0.0014852223685011268, 0.7791083455085754]], [[0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527], [0.1422717422246933, 0.04722162336111069, 0.015745365992188454, 0.03852943703532219, 0.03582964092493057, 0.15023833513259888, 0.08256732672452927, 0.10793514549732208, 0.34277576208114624, 0.03688564524054527]]]], \"bot_text\": [\"I_\", \" &_\", \"apos_\", \";_\", \"m_\", \"a_\", \"good_\", \"teacher_\", \" ._\"]}, \"inp_inp\": {\"top_text\": [\"T\\u00f4i_\", \"l\\u00e0_\", \"m\\u1ed9t_\", \"th\\u1ea7y_\", \"gi\\u00e1o_\", \"gi\\u1ecfi_\"], \"att\": [[[[0.15637657046318054, 0.031179480254650116, 0.0591559112071991, 0.03467392176389694, 0.01973690837621689, 0.06068029627203941, 0.6381968855857849], [0.24990732967853546, 0.04834190756082535, 0.16599032282829285, 0.08423759043216705, 0.04652909189462662, 0.08058451116085052, 0.32440927624702454], [0.010967226698994637, 0.02172553725540638, 0.03470718488097191, 0.14958412945270538, 0.23588316142559052, 0.5219144225120544, 0.025218378752470016], [0.0061057014390826225, 0.0021930125076323748, 0.010520044714212418, 0.215690478682518, 0.4664883017539978, 0.23077654838562012, 0.06822594255208969], [0.004976624622941017, 0.0006474226247519255, 0.0038635318633168936, 0.4096323549747467, 0.13856898248195648, 0.38877660036087036, 0.05353453755378723], [0.0020405075047165155, 0.000558990694116801, 0.002208310877904296, 0.010428190231323242, 0.05572662502527237, 0.09833728522062302, 0.8307000994682312], [0.04859629273414612, 0.0992843508720398, 0.024837173521518707, 0.022672463208436966, 0.041493821889162064, 0.10241886973381042, 0.6606969833374023]], [[0.08919383585453033, 0.5788573622703552, 0.2900116443634033, 0.00536323431879282, 0.0054911295883357525, 0.010270982049405575, 0.020811777561903], [0.05315522477030754, 0.05477380007505417, 0.7107505202293396, 0.07555636018514633, 0.044316332787275314, 0.0329383946955204, 0.028509408235549927], [0.004811703693121672, 0.05610184371471405, 0.023363150656223297, 0.04314766079187393, 0.19077634811401367, 0.451174259185791, 0.23062501847743988], [0.01629498414695263, 0.008990052156150341, 0.016501707956194878, 0.003588054794818163, 0.04053742438554764, 0.10115395486354828, 0.8129338026046753], [0.0022456306032836437, 0.002136725466698408, 0.0011441110400483012, 0.00033694354351609945, 0.00807734951376915, 0.06298699975013733, 0.9230722188949585], [0.025586603209376335, 0.008633822202682495, 0.004241446498781443, 0.0016273887595161796, 0.012170940637588501, 0.049063485115766525, 0.898676335811615], [0.03341146558523178, 0.02379998005926609, 0.010208996944129467, 0.002263963920995593, 0.006787281483411789, 0.0869273841381073, 0.8366009593009949]], [[0.1794050633907318, 0.10620228201150894, 0.08233162015676498, 0.12294647097587585, 0.03687690570950508, 0.06893271207809448, 0.40330493450164795], [0.39334648847579956, 0.026603734120726585, 0.30390098690986633, 0.012356402352452278, 0.0041913981549441814, 0.03003511391580105, 0.22956588864326477], [0.027390550822019577, 0.16503988206386566, 0.04586160555481911, 0.2302263230085373, 0.13011474907398224, 0.29631760716438293, 0.10504936426877975], [0.005118991248309612, 0.005646487697958946, 0.012889642268419266, 0.46222004294395447, 0.26949939131736755, 0.07023416459560394, 0.17439128458499908], [0.004886195063591003, 0.0028036495205014944, 0.016034258529543877, 0.4406549036502838, 0.09583024680614471, 0.15249089896678925, 0.28729987144470215], [0.009601201862096786, 0.0009394164080731571, 0.014605253003537655, 0.05758216604590416, 0.1045263409614563, 0.16328158974647522, 0.6494640111923218], [0.0011346392566338181, 0.00190354126971215, 0.0005144121241755784, 0.0032229411881417036, 0.0033254751469939947, 0.05584224686026573, 0.9340567588806152]], [[0.23925544321537018, 0.1495950073003769, 0.074134960770607, 0.13400912284851074, 0.036855194717645645, 0.20192593336105347, 0.16422437131404877], [0.4463321268558502, 0.08793879300355911, 0.11290805786848068, 0.13659793138504028, 0.0393790677189827, 0.09606495499610901, 0.0807790756225586], [0.22583530843257904, 0.1117587611079216, 0.11304541677236557, 0.22597678005695343, 0.07174260914325714, 0.14210860431194305, 0.10953247547149658], [0.21184861660003662, 0.11912985891103745, 0.08142074197530746, 0.20865124464035034, 0.125769704580307, 0.16199974715709686, 0.09118017554283142], [0.13423313200473785, 0.04413554072380066, 0.0810641422867775, 0.4767560660839081, 0.09756991267204285, 0.11681855469942093, 0.04942258074879646], [0.09112156927585602, 0.1221369057893753, 0.29441726207733154, 0.15917669236660004, 0.17216818034648895, 0.1071373000741005, 0.05384201183915138], [0.12218175083398819, 0.29104188084602356, 0.18802489340305328, 0.13109752535820007, 0.08446026593446732, 0.11128930002450943, 0.07190437614917755]]], [[[0.033222347497940063, 0.01117094699293375, 0.004438965581357479, 0.014089155942201614, 0.013568120077252388, 0.08421560376882553, 0.839294970035553], [0.9909290671348572, 0.0031243504490703344, 0.0009099586750380695, 0.00044803490163758397, 0.00017059814126696438, 0.0004778687725774944, 0.00394014036282897], [0.026670319959521294, 0.8587448596954346, 0.09465216100215912, 0.01478393655270338, 0.002567719668149948, 0.001430327189154923, 0.001150674419477582], [5.5622564104851335e-05, 0.0029673262033611536, 0.9571806788444519, 0.032983843237161636, 0.004578517284244299, 0.0019641409162431955, 0.00026985432486981153], [0.00016515454626642168, 0.0006547846714965999, 0.6357616186141968, 0.2341514378786087, 0.05240916088223457, 0.07244595885276794, 0.004411905072629452], [0.00032206965261138976, 4.0217168134404346e-05, 0.10160578787326813, 0.24953864514827728, 0.3993138372898102, 0.1859280914068222, 0.06325137615203857], [0.0007896021706983447, 0.00010236073285341263, 0.0023883029352873564, 0.08584544062614441, 0.21642054617404938, 0.6267321705818176, 0.06772156059741974]], [[0.013507821597158909, 0.003428569296374917, 0.0005854362389072776, 0.0008416551863774657, 0.0004880995547864586, 0.0008058223174884915, 0.9803426265716553], [0.822248637676239, 0.04045531526207924, 0.01175216119736433, 0.0021381382830441, 0.0019350502407178283, 0.003611659398302436, 0.11785909533500671], [0.15152117609977722, 0.685112476348877, 0.14481458067893982, 0.00551303057000041, 0.0018123624613508582, 0.002342620864510536, 0.008883670903742313], [0.010127967223525047, 0.18935945630073547, 0.777565062046051, 0.005309808999300003, 0.002551265060901642, 0.009146109223365784, 0.005940355826169252], [0.008314592763781548, 0.0869276374578476, 0.83534836769104, 0.011873320676386356, 0.008547228761017323, 0.041367579251527786, 0.007621485739946365], [0.007179880980402231, 0.013340642675757408, 0.8176888227462769, 0.021866271272301674, 0.03257835656404495, 0.06856315582990646, 0.03878301754593849], [0.001468008616939187, 0.00106660439632833, 0.030770542100071907, 0.06526954472064972, 0.15483789145946503, 0.7391741275787354, 0.007413213141262531]], [[0.24491305649280548, 0.2716386020183563, 0.2974568009376526, 0.0715150237083435, 0.032737474888563156, 0.03313692659139633, 0.048602212220430374], [0.06463561207056046, 0.0433550626039505, 0.5164699554443359, 0.2553751766681671, 0.05558573082089424, 0.03877051919698715, 0.02580798976123333], [0.005344105418771505, 0.004306877497583628, 0.02483231946825981, 0.35550329089164734, 0.18227519094944, 0.35200417041778564, 0.07573401182889938], [0.002322714775800705, 0.001051871688105166, 0.025118347257375717, 0.03140588477253914, 0.10554895550012589, 0.6380510926246643, 0.19650113582611084], [0.0009995860746130347, 0.0004442579811438918, 0.0043803914450109005, 0.010685287415981293, 0.04103739187121391, 0.6786168217658997, 0.2638362944126129], [0.006038180086761713, 0.0021745343692600727, 0.006020124536007643, 0.011885320767760277, 0.07246774435043335, 0.3011493384838104, 0.6002647280693054], [0.14067502319812775, 0.06330223381519318, 0.04618984833359718, 0.025883490219712257, 0.09871792048215866, 0.17052823305130005, 0.45470327138900757]], [[0.10726487636566162, 0.040105823427438736, 0.03365788608789444, 0.05795503780245781, 0.02877318300306797, 0.06775611639022827, 0.6644870638847351], [0.16149355471134186, 0.0507226437330246, 0.043050073087215424, 0.04469142109155655, 0.04235309362411499, 0.04066084325313568, 0.6170283555984497], [0.34940773248672485, 0.09805944561958313, 0.0713985413312912, 0.056111957877874374, 0.03563306853175163, 0.04191041365265846, 0.34747880697250366], [0.3118698298931122, 0.2712187170982361, 0.11745087802410126, 0.032837074249982834, 0.015879064798355103, 0.04398801550269127, 0.20675639808177948], [0.2673729360103607, 0.26532304286956787, 0.209498792886734, 0.034180257469415665, 0.013117877766489983, 0.045311469584703445, 0.16519568860530853], [0.09899894893169403, 0.24890649318695068, 0.2992298901081085, 0.06689880788326263, 0.04724286496639252, 0.05928840488195419, 0.1794346570968628], [0.20271816849708557, 0.14796458184719086, 0.23876041173934937, 0.08937732130289078, 0.07028388977050781, 0.09505382925271988, 0.15584181249141693]]]], \"bot_text\": [\"T\\u00f4i_\", \"l\\u00e0_\", \"m\\u1ed9t_\", \"th\\u1ea7y_\", \"gi\\u00e1o_\", \"gi\\u1ecfi_\"]}}" - ], - "text/plain": [ - "" - ] - }, - "metadata": { - "tags": [] - } - }, - { - "output_type": "display_data", - "data": { - "application/javascript": [ - "/**\n", - " * @fileoverview Transformer Visualization D3 javascript code.\n", - " */\n", - "\n", - "requirejs(['jquery', 'd3'],\n", - "function($, d3) {\n", - "\n", - "var attention = window.attention;\n", - "\n", - "const TEXT_SIZE = 15;\n", - "const BOXWIDTH = TEXT_SIZE * 8;\n", - "const BOXHEIGHT = TEXT_SIZE * 1.5;\n", - "const WIDTH = 2000;\n", - "const HEIGHT = attention.all.bot_text.length * BOXHEIGHT * 2 + 100;\n", - "const MATRIX_WIDTH = 150;\n", - "const head_colours = d3.scale.category10();\n", - "const CHECKBOX_SIZE = 20;\n", - "\n", - "function lighten(colour) {\n", - " var c = d3.hsl(colour);\n", - " var increment = (1 - c.l) * 0.6;\n", - " c.l += increment;\n", - " c.s -= increment;\n", - " return c;\n", - "}\n", - "\n", - "function transpose(mat) {\n", - " return mat[0].map(function(col, i) {\n", - " return mat.map(function(row) {\n", - " return row[i];\n", - " });\n", - " });\n", - "}\n", - "\n", - "function zip(a, b) {\n", - " return a.map(function (e, i) {\n", - " return [e, b[i]];\n", - " });\n", - "}\n", - "\n", - "\n", - "function renderVis(id, top_text, bot_text, attention_heads, config) {\n", - " $(id).empty();\n", - " var svg = d3.select(id)\n", - " .append('svg')\n", - " .attr(\"width\", WIDTH)\n", - " .attr(\"height\", HEIGHT);\n", - "\n", - " var att_data = [];\n", - " for (var i=0; i < attention_heads.length; i++) {\n", - " var att_trans = transpose(attention_heads[i]);\n", - " att_data.push(zip(attention_heads[i], att_trans));\n", - " }\n", - "\n", - " renderText(svg, top_text, true, att_data, 0);\n", - " renderText(svg, bot_text, false, att_data, MATRIX_WIDTH + BOXWIDTH);\n", - "\n", - " renderAttentionHighlights(svg, att_data);\n", - "\n", - " svg.append(\"g\").classed(\"attention_heads\", true);\n", - "\n", - " renderAttention(svg, attention_heads);\n", - "\n", - " draw_checkboxes(config, 0, svg, attention_heads);\n", - "}\n", - "\n", - "\n", - "function renderText(svg, text, is_top, att_data, left_pos) {\n", - " var id = is_top ? \"top\" : \"bottom\";\n", - " var textContainer = svg.append(\"svg:g\")\n", - " .attr(\"id\", id);\n", - "\n", - " textContainer.append(\"g\").classed(\"attention_boxes\", true)\n", - " .selectAll(\"g\")\n", - " .data(att_data)\n", - " .enter()\n", - " .append(\"g\")\n", - " .selectAll(\"rect\")\n", - " .data(function(d) {return d;})\n", - " .enter()\n", - " .append(\"rect\")\n", - " .attr(\"x\", function(d, i, j) {\n", - " return left_pos + box_offset(j);\n", - " })\n", - " .attr(\"y\", function(d, i) {\n", - " return (+1) * BOXHEIGHT;\n", - " })\n", - " .attr(\"width\", BOXWIDTH/active_heads())\n", - " .attr(\"height\", function() { return BOXHEIGHT; })\n", - " .attr(\"fill\", function(d, i, j) {\n", - " return head_colours(j);\n", - " })\n", - " .style(\"opacity\", 0.0);\n", - "\n", - "\n", - " var tokenContainer = textContainer.append(\"g\").selectAll(\"g\")\n", - " .data(text)\n", - " .enter()\n", - " .append(\"g\");\n", - "\n", - " tokenContainer.append(\"rect\")\n", - " .classed(\"background\", true)\n", - " .style(\"opacity\", 0.0)\n", - " .attr(\"fill\", \"lightgray\")\n", - " .attr(\"x\", left_pos)\n", - " .attr(\"y\", function(d, i) {\n", - " return (i+1) * BOXHEIGHT;\n", - " })\n", - " .attr(\"width\", BOXWIDTH)\n", - " .attr(\"height\", BOXHEIGHT);\n", - "\n", - " var theText = tokenContainer.append(\"text\")\n", - " .text(function(d) { return d; })\n", - " .attr(\"font-size\", TEXT_SIZE + \"px\")\n", - " .style(\"cursor\", \"default\")\n", - " .style(\"-webkit-user-select\", \"none\")\n", - " .attr(\"x\", left_pos)\n", - " .attr(\"y\", function(d, i) {\n", - " return (i+1) * BOXHEIGHT;\n", - " });\n", - "\n", - " if (is_top) {\n", - " theText.style(\"text-anchor\", \"end\")\n", - " .attr(\"dx\", BOXWIDTH - TEXT_SIZE)\n", - " .attr(\"dy\", TEXT_SIZE);\n", - " } else {\n", - " theText.style(\"text-anchor\", \"start\")\n", - " .attr(\"dx\", + TEXT_SIZE)\n", - " .attr(\"dy\", TEXT_SIZE);\n", - " }\n", - "\n", - " tokenContainer.on(\"mouseover\", function(d, index) {\n", - " textContainer.selectAll(\".background\")\n", - " .style(\"opacity\", function(d, i) {\n", - " return i == index ? 1.0 : 0.0;\n", - " });\n", - "\n", - " svg.selectAll(\".attention_heads\").style(\"display\", \"none\");\n", - "\n", - " svg.selectAll(\".line_heads\") // To get the nesting to work.\n", - " .selectAll(\".att_lines\")\n", - " .attr(\"stroke-opacity\", function(d) {\n", - " return 1.0;\n", - " })\n", - " .attr(\"y1\", function(d, i) {\n", - " if (is_top) {\n", - " return (index+1) * BOXHEIGHT + (BOXHEIGHT/2);\n", - " } else {\n", - " return (i+1) * BOXHEIGHT + (BOXHEIGHT/2);\n", - " }\n", - " })\n", - " .attr(\"x1\", BOXWIDTH)\n", - " .attr(\"y2\", function(d, i) {\n", - " if (is_top) {\n", - " return (i+1) * BOXHEIGHT + (BOXHEIGHT/2);\n", - " } else {\n", - " return (index+1) * BOXHEIGHT + (BOXHEIGHT/2);\n", - " }\n", - " })\n", - " .attr(\"x2\", BOXWIDTH + MATRIX_WIDTH)\n", - " .attr(\"stroke-width\", 2)\n", - " .attr(\"stroke\", function(d, i, j) {\n", - " return head_colours(j);\n", - " })\n", - " .attr(\"stroke-opacity\", function(d, i, j) {\n", - " if (is_top) {d = d[0];} else {d = d[1];}\n", - " if (config.head_vis[j]) {\n", - " if (d) {\n", - " return d[index];\n", - " } else {\n", - " return 0.0;\n", - " }\n", - " } else {\n", - " return 0.0;\n", - " }\n", - " });\n", - "\n", - "\n", - " function updateAttentionBoxes() {\n", - " var id = is_top ? \"bottom\" : \"top\";\n", - " var the_left_pos = is_top ? MATRIX_WIDTH + BOXWIDTH : 0;\n", - " svg.select(\"#\" + id)\n", - " .selectAll(\".attention_boxes\")\n", - " .selectAll(\"g\")\n", - " .selectAll(\"rect\")\n", - " .attr(\"x\", function(d, i, j) { return the_left_pos + box_offset(j); })\n", - " .attr(\"y\", function(d, i) { return (i+1) * BOXHEIGHT; })\n", - " .attr(\"width\", BOXWIDTH/active_heads())\n", - " .attr(\"height\", function() { return BOXHEIGHT; })\n", - " .style(\"opacity\", function(d, i, j) {\n", - " if (is_top) {d = d[0];} else {d = d[1];}\n", - " if (config.head_vis[j])\n", - " if (d) {\n", - " return d[index];\n", - " } else {\n", - " return 0.0;\n", - " }\n", - " else\n", - " return 0.0;\n", - "\n", - " });\n", - " }\n", - "\n", - " updateAttentionBoxes();\n", - " });\n", - "\n", - " textContainer.on(\"mouseleave\", function() {\n", - " d3.select(this).selectAll(\".background\")\n", - " .style(\"opacity\", 0.0);\n", - "\n", - " svg.selectAll(\".att_lines\").attr(\"stroke-opacity\", 0.0);\n", - " svg.selectAll(\".attention_heads\").style(\"display\", \"inline\");\n", - " svg.selectAll(\".attention_boxes\")\n", - " .selectAll(\"g\")\n", - " .selectAll(\"rect\")\n", - " .style(\"opacity\", 0.0);\n", - " });\n", - "}\n", - "\n", - "function renderAttentionHighlights(svg, attention) {\n", - " var line_container = svg.append(\"g\");\n", - " line_container.selectAll(\"g\")\n", - " .data(attention)\n", - " .enter()\n", - " .append(\"g\")\n", - " .classed(\"line_heads\", true)\n", - " .selectAll(\"line\")\n", - " .data(function(d){return d;})\n", - " .enter()\n", - " .append(\"line\").classed(\"att_lines\", true);\n", - "}\n", - "\n", - "function renderAttention(svg, attention_heads) {\n", - " var line_container = svg.selectAll(\".attention_heads\");\n", - " line_container.html(null);\n", - " for(var h=0; h\").val(i).text(i));\n", - "}\n", - "\n", - "$(\"#layer\").on('change', function(e) {\n", - " config.layer = +e.currentTarget.value;\n", - " render();\n", - "});\n", - "\n", - "$(\"#att_type\").on('change', function(e) {\n", - " config.att_type = e.currentTarget.value;\n", - " render();\n", - "});\n", - "\n", - "$(\"button\").on('click', visualize);\n", - "\n", - "visualize();\n", - "\n", - "});\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": { - "tags": [] - } - } - ] + "outputs": [] }, { "cell_type": "markdown", @@ -1457,11 +651,7 @@ "id": "hEoMmnXO2UaZ", "colab_type": "code", "cellView": "both", - "outputId": "5c922bc7-4855-44b4-ad4d-190fe40c4b86", - "colab": { - "base_uri": "https://localhost:8080/", - "height": 52 - } + "colab": {} }, "source": [ "beam_size = 4 #@param {type: \"integer\"}\n", @@ -1475,16 +665,7 @@ "print(vi_output_sentence)\n" ], "execution_count": 0, - "outputs": [ - { - "output_type": "stream", - "text": [ - "Augmented data:\n", - "Tôi đã từng mơ ước là một người chơi bóng đá .\n" - ], - "name": "stdout" - } - ] + "outputs": [] }, { "cell_type": "markdown",