diff --git a/3D-with-NLP_version2.ipynb b/3D-with-NLP_version2.ipynb new file mode 100644 index 0000000..5d7a864 --- /dev/null +++ b/3D-with-NLP_version2.ipynb @@ -0,0 +1,21595 @@ +{ + "nbformat": 4, + "nbformat_minor": 5, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + }, + "colab": { + "name": "NLP-version2.ipynb", + "provenance": [] + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "f96bc6931f7e48008d1a0e3d51c13c29": { + "model_module": "@jupyter-widgets/controls", + "model_name": "IntProgressModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "ProgressView", + "style": "IPY_MODEL_6ec67b6b9d7a43ad9cac0f5234547b6a", + "_dom_classes": [], + "description": "Processing: ", + "_model_name": "IntProgressModel", + "bar_style": "", + "max": 11, + "_view_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "value": 11, + "_view_count": null, + "_view_module_version": "1.5.0", + "orientation": "horizontal", + "min": 0, + "description_tooltip": null, + "_model_module": "@jupyter-widgets/controls", + "layout": "IPY_MODEL_d1e95ef266824c5cbce98b438f5e5d05" + } + }, + "6ec67b6b9d7a43ad9cac0f5234547b6a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "StyleView", + "_model_name": "ProgressStyleModel", + "description_width": "", + "_view_module": "@jupyter-widgets/base", + "_model_module_version": "1.5.0", + "_view_count": null, + "_view_module_version": "1.2.0", + "bar_color": null, + "_model_module": "@jupyter-widgets/controls" + } + }, + "d1e95ef266824c5cbce98b438f5e5d05": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_view_name": "LayoutView", + "grid_template_rows": null, + "right": null, + "justify_content": null, + "_view_module": "@jupyter-widgets/base", + "overflow": null, + "_model_module_version": "1.2.0", + "_view_count": null, + "flex_flow": null, + "width": null, + "min_width": null, + "border": null, + "align_items": null, + "bottom": null, + "_model_module": "@jupyter-widgets/base", + "top": null, + "grid_column": null, + "overflow_y": null, + "overflow_x": null, + "grid_auto_flow": null, + "grid_area": null, + "grid_template_columns": null, + "flex": null, + "_model_name": "LayoutModel", + "justify_items": null, + "grid_row": null, + "max_height": null, + "align_content": null, + "visibility": null, + "align_self": null, + "height": null, + "min_height": null, + "padding": null, + "grid_auto_rows": null, + "grid_gap": null, + "max_width": null, + "order": null, + "_view_module_version": "1.2.0", + "grid_template_areas": null, + "object_position": null, + "object_fit": null, + "grid_auto_columns": null, + "margin": null, + "display": null, + "left": null + } + }, + "3859d91a1623426e85e9c43e26dba780": { + "model_module": "@jupyter-widgets/controls", + "model_name": "IntProgressModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "ProgressView", + "style": "IPY_MODEL_271f027241d543d38ea4c444244d106b", + "_dom_classes": [], + "description": "Processing: ", + "_model_name": "IntProgressModel", + "bar_style": "", + "max": 1718, + "_view_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "value": 1717, + "_view_count": null, + "_view_module_version": "1.5.0", + "orientation": "horizontal", + "min": 0, + "description_tooltip": null, + "_model_module": "@jupyter-widgets/controls", + "layout": "IPY_MODEL_49eb6fd8239b4b629af0e97b72e30568" + } + }, + "271f027241d543d38ea4c444244d106b": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "StyleView", + "_model_name": "ProgressStyleModel", + "description_width": "", + "_view_module": "@jupyter-widgets/base", + "_model_module_version": "1.5.0", + "_view_count": null, + "_view_module_version": "1.2.0", + "bar_color": null, + "_model_module": "@jupyter-widgets/controls" + } + }, + "49eb6fd8239b4b629af0e97b72e30568": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_view_name": "LayoutView", + "grid_template_rows": null, + "right": null, + "justify_content": null, + "_view_module": "@jupyter-widgets/base", + "overflow": null, + "_model_module_version": "1.2.0", + "_view_count": null, + "flex_flow": null, + "width": null, + "min_width": null, + "border": null, + "align_items": null, + "bottom": null, + "_model_module": "@jupyter-widgets/base", + "top": null, + "grid_column": null, + "overflow_y": null, + "overflow_x": null, + "grid_auto_flow": null, + "grid_area": null, + "grid_template_columns": null, + "flex": null, + "_model_name": "LayoutModel", + "justify_items": null, + "grid_row": null, + "max_height": null, + "align_content": null, + "visibility": null, + "align_self": null, + "height": null, + "min_height": null, + "padding": null, + "grid_auto_rows": null, + "grid_gap": null, + "max_width": null, + "order": null, + "_view_module_version": "1.2.0", + "grid_template_areas": null, + "object_position": null, + "object_fit": null, + "grid_auto_columns": null, + "margin": null, + "display": null, + "left": null + } + }, + "748dee4c99d249dfac20be52270ac3a6": { + "model_module": "@jupyter-widgets/controls", + "model_name": "IntProgressModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "ProgressView", + "style": "IPY_MODEL_497556b91c3f46968a4cd5e4ebb26376", + "_dom_classes": [], + "description": "Processing: ", + "_model_name": "IntProgressModel", + "bar_style": "", + "max": 1718, + "_view_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "value": 1718, + "_view_count": null, + "_view_module_version": "1.5.0", + "orientation": "horizontal", + "min": 0, + "description_tooltip": null, + "_model_module": "@jupyter-widgets/controls", + "layout": "IPY_MODEL_6b6723ce383e43ccbdfdd5f1170234b4" + } + }, + "497556b91c3f46968a4cd5e4ebb26376": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "StyleView", + "_model_name": "ProgressStyleModel", + "description_width": "", + "_view_module": "@jupyter-widgets/base", + "_model_module_version": "1.5.0", + "_view_count": null, + "_view_module_version": "1.2.0", + "bar_color": null, + "_model_module": "@jupyter-widgets/controls" + } + }, + "6b6723ce383e43ccbdfdd5f1170234b4": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_view_name": "LayoutView", + "grid_template_rows": null, + "right": null, + "justify_content": null, + "_view_module": "@jupyter-widgets/base", + "overflow": null, + "_model_module_version": "1.2.0", + "_view_count": null, + "flex_flow": null, + "width": null, + "min_width": null, + "border": null, + "align_items": null, + "bottom": null, + "_model_module": "@jupyter-widgets/base", + "top": null, + "grid_column": null, + "overflow_y": null, + "overflow_x": null, + "grid_auto_flow": null, + "grid_area": null, + "grid_template_columns": null, + "flex": null, + "_model_name": "LayoutModel", + "justify_items": null, + "grid_row": null, + "max_height": null, + "align_content": null, + "visibility": null, + "align_self": null, + "height": null, + "min_height": null, + "padding": null, + "grid_auto_rows": null, + "grid_gap": null, + "max_width": null, + "order": null, + "_view_module_version": "1.2.0", + "grid_template_areas": null, + "object_position": null, + "object_fit": null, + "grid_auto_columns": null, + "margin": null, + "display": null, + "left": null + } + }, + "9160c088bf39460da64dbad6bd54bdc0": { + "model_module": "@jupyter-widgets/controls", + "model_name": "IntProgressModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "ProgressView", + "style": "IPY_MODEL_41ce9036c91846fea09a3f4893d2d158", + "_dom_classes": [], + "description": "Processing: ", + "_model_name": "IntProgressModel", + "bar_style": "", + "max": 25, + "_view_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "value": 22, + "_view_count": null, + "_view_module_version": "1.5.0", + "orientation": "horizontal", + "min": 0, + "description_tooltip": null, + "_model_module": "@jupyter-widgets/controls", + "layout": "IPY_MODEL_7d96941448f44a45853a329dc88d8743" + } + }, + "41ce9036c91846fea09a3f4893d2d158": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_view_name": "StyleView", + "_model_name": "ProgressStyleModel", + "description_width": "", + "_view_module": "@jupyter-widgets/base", + "_model_module_version": "1.5.0", + "_view_count": null, + "_view_module_version": "1.2.0", + "bar_color": null, + "_model_module": "@jupyter-widgets/controls" + } + }, + "7d96941448f44a45853a329dc88d8743": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_view_name": "LayoutView", + "grid_template_rows": null, + "right": null, + "justify_content": null, + "_view_module": "@jupyter-widgets/base", + "overflow": null, + "_model_module_version": "1.2.0", + "_view_count": null, + "flex_flow": null, + "width": null, + "min_width": null, + "border": null, + "align_items": null, + "bottom": null, + "_model_module": "@jupyter-widgets/base", + "top": null, + "grid_column": null, + "overflow_y": null, + "overflow_x": null, + "grid_auto_flow": null, + "grid_area": null, + "grid_template_columns": null, + "flex": null, + "_model_name": "LayoutModel", + "justify_items": null, + "grid_row": null, + "max_height": null, + "align_content": null, + "visibility": null, + "align_self": null, + "height": null, + "min_height": null, + "padding": null, + "grid_auto_rows": null, + "grid_gap": null, + "max_width": null, + "order": null, + "_view_module_version": "1.2.0", + "grid_template_areas": null, + "object_position": null, + "object_fit": null, + "grid_auto_columns": null, + "margin": null, + "display": null, + "left": null + } + }, + "024de908ddd9428dafdd3ee7c601ddf7": { + "model_module": "@jupyter-widgets/output", + "model_name": "OutputModel", + "model_module_version": "1.0.0", + "state": { + "_view_name": "OutputView", + "msg_id": "", + "_dom_classes": [], + "_model_name": "OutputModel", + "outputs": [], + "_view_module": "@jupyter-widgets/output", + "_model_module_version": "1.0.0", + "_view_count": null, + "_view_module_version": "1.0.0", + "layout": "IPY_MODEL_b24a7506146f49f8a20bfa822bb7a961", + "_model_module": "@jupyter-widgets/output" + } + }, + "b24a7506146f49f8a20bfa822bb7a961": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_view_name": "LayoutView", + "grid_template_rows": null, + "right": null, + "justify_content": null, + "_view_module": "@jupyter-widgets/base", + "overflow": null, + "_model_module_version": "1.2.0", + "_view_count": null, + "flex_flow": null, + "width": null, + "min_width": null, + "border": null, + "align_items": null, + "bottom": null, + "_model_module": "@jupyter-widgets/base", + "top": null, + "grid_column": null, + "overflow_y": null, + "overflow_x": null, + "grid_auto_flow": null, + "grid_area": null, + "grid_template_columns": null, + "flex": null, + "_model_name": "LayoutModel", + "justify_items": null, + "grid_row": null, + "max_height": null, + "align_content": null, + "visibility": null, + "align_self": null, + "height": null, + "min_height": null, + "padding": null, + "grid_auto_rows": null, + "grid_gap": null, + "max_width": null, + "order": null, + "_view_module_version": "1.2.0", + "grid_template_areas": null, + "object_position": null, + "object_fit": null, + "grid_auto_columns": null, + "margin": null, + "display": null, + "left": null + } + } + } + } + }, + "cells": [ + { + "cell_type": "code", + "metadata": { + "id": "34e4ee78" + }, + "source": [ + "import nltk\n", + "import pandas as pd\n", + "import numpy as np\n", + "import re\n", + "import regex\n", + "import string\n", + "from sklearn.feature_extraction.text import CountVectorizer\n", + "from nltk.stem.porter import PorterStemmer\n", + "from nltk.stem.lancaster import LancasterStemmer\n", + "from nltk.tokenize import word_tokenize\n", + "from nltk.stem import WordNetLemmatizer\n", + "from sklearn.decomposition import NMF\n", + "import string\n", + "import gensim \n", + "from sklearn.decomposition import TruncatedSVD\n", + "import matplotlib.pyplot as plt\n", + "import seaborn as sns\n", + "from gensim.corpora import Dictionary\n", + "\n", + "from gensim.models import CoherenceModel" + ], + "id": "34e4ee78", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "75d9222e" + }, + "source": [ + "" + ], + "id": "75d9222e", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f5111464" + }, + "source": [ + "df=pd.read_csv('reddit.csv')" + ], + "id": "f5111464", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "2027e67e" + }, + "source": [ + "### EDA & Data Cleaning " + ], + "id": "2027e67e" + }, + { + "cell_type": "code", + "metadata": { + "id": "75c47409" + }, + "source": [ + "df.head()\n", + "df.drop('Unnamed: 0',axis=1,inplace=True)\n" + ], + "id": "75c47409", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "8443648b" + }, + "source": [ + "#remove empty rows\n", + "df.dropna(inplace=True)\n", + "df.reset_index(inplace=True)" + ], + "id": "8443648b", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 49 + }, + "id": "f978b69a", + "outputId": "b7b94e2d-f569-46ff-b1a3-5d6ac8c65129" + }, + "source": [ + "#check for duplicates \n", + "df[df.duplicated()]" + ], + "id": "f978b69a", + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indextitlepost
\n", + "
" + ], + "text/plain": [ + "Empty DataFrame\n", + "Columns: [index, title, post]\n", + "Index: []" + ] + }, + "metadata": {}, + "execution_count": 6 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a725f3b0" + }, + "source": [ + "#df.drop('level_0',axis=1,inplace=True)\n", + "df.drop('index',axis=1,inplace=True)\n" + ], + "id": "a725f3b0", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + }, + "id": "ad0b5f1a", + "outputId": "e942a1b8-e0bc-4ab6-f447-08a4fbb4d68e" + }, + "source": [ + "df.head()" + ], + "id": "ad0b5f1a", + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titlepost
0any good military text-based rpg?Hey guys\\n\\nI used to play a game from Storm8 ...
1FC 6 Defeat Admiral Benitez BROKENIn one try I fell trough a “floor” into broken...
2Games with great sound designWe can all appreciate good sound, right? But w...
3I need a game recommendationHi all,\\n\\nI'm 72, retired, and bored to tears...
4Why did Valve made that terrible card game?I like Valve since they usually do a good job ...
\n", + "
" + ], + "text/plain": [ + " title post\n", + "0 any good military text-based rpg? Hey guys\\n\\nI used to play a game from Storm8 ...\n", + "1 FC 6 Defeat Admiral Benitez BROKEN In one try I fell trough a “floor” into broken...\n", + "2 Games with great sound design We can all appreciate good sound, right? But w...\n", + "3 I need a game recommendation Hi all,\\n\\nI'm 72, retired, and bored to tears...\n", + "4 Why did Valve made that terrible card game? I like Valve since they usually do a good job ..." + ] + }, + "metadata": {}, + "execution_count": 8 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 204 + }, + "id": "b2740533", + "outputId": "4589631d-c9a0-4385-a4b1-6ce2aa179cc0" + }, + "source": [ + "df.head()" + ], + "id": "b2740533", + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titlepost
0any good military text-based rpg?Hey guys\\n\\nI used to play a game from Storm8 ...
1FC 6 Defeat Admiral Benitez BROKENIn one try I fell trough a “floor” into broken...
2Games with great sound designWe can all appreciate good sound, right? But w...
3I need a game recommendationHi all,\\n\\nI'm 72, retired, and bored to tears...
4Why did Valve made that terrible card game?I like Valve since they usually do a good job ...
\n", + "
" + ], + "text/plain": [ + " title post\n", + "0 any good military text-based rpg? Hey guys\\n\\nI used to play a game from Storm8 ...\n", + "1 FC 6 Defeat Admiral Benitez BROKEN In one try I fell trough a “floor” into broken...\n", + "2 Games with great sound design We can all appreciate good sound, right? But w...\n", + "3 I need a game recommendation Hi all,\\n\\nI'm 72, retired, and bored to tears...\n", + "4 Why did Valve made that terrible card game? I like Valve since they usually do a good job ..." + ] + }, + "metadata": {}, + "execution_count": 9 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "482c6f57" + }, + "source": [ + "#URL link removal\n", + "removeUrl = lambda x: re.sub('https?:\\/\\/[\\da-z\\.-]+\\.[a-z\\.]{2,6}[^\\s]+', \"\", x)\n", + "df['post']=df.post.map(removeUrl)" + ], + "id": "482c6f57", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "dc2b0363", + "outputId": "4eebefbe-4a3c-478e-8bd4-b4d2693a74d1" + }, + "source": [ + "nltk.download('punkt')" + ], + "id": "dc2b0363", + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "[nltk_data] Downloading package punkt to /root/nltk_data...\n", + "[nltk_data] Package punkt is already up-to-date!\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "True" + ] + }, + "metadata": {}, + "execution_count": 10 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "a80280ac" + }, + "source": [ + "#text lower and number removal \n", + "df['post']= df['post'].apply(lambda x: x.lower())\n", + "remove_num = lambda x: re.sub('\\w*\\d\\w*', ' ', x)\n", + "df['post']=df.post.map(remove_num)" + ], + "id": "a80280ac", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "SFvhcdUB3SBm" + }, + "source": [ + "import os\n", + "import pandas as pd\n", + "import pycaret\n", + "from pycaret.nlp import *" + ], + "id": "SFvhcdUB3SBm", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "KOYfABZl3R0k" + }, + "source": [ + "" + ], + "id": "KOYfABZl3R0k", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "722aa918" + }, + "source": [ + "# toknize\n", + "df['post']=df.post.map(word_tokenize)" + ], + "id": "722aa918", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 173, + "referenced_widgets": [ + "f96bc6931f7e48008d1a0e3d51c13c29", + "6ec67b6b9d7a43ad9cac0f5234547b6a", + "d1e95ef266824c5cbce98b438f5e5d05" + ] + }, + "id": "4f94d0dc", + "outputId": "ea3fc530-f483-4bad-9ac0-cbaf9b52c125" + }, + "source": [ + "# initialize the setup\n", + "nlp = setup(data = df, target = 'post', session_id = 493, custom_stopwords = ['would','make','also','get','still','way','like','much','nbsp','think','could','well','feel','know','\"','.',\n", + " ',',\n", + " '--',\n", + " '\\'s',\n", + " '?',\n", + " ')',\n", + " '(',\n", + " ':',\n", + " '\\'',\n", + " '\\'re',\n", + " '\"',\n", + " '-',\n", + " '}',\n", + " '{',\n", + " u'—','hi','hey','”','“'])" + ], + "id": "4f94d0dc", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Description Value
session_id493
Documents1713
Vocab Size7106
Custom StopwordsTrue
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ROGCIg0NB2Bw" + }, + "source": [ + "rp = create_model('rp', num_topics = 6, multi_core = True)" + ], + "id": "ROGCIg0NB2Bw", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "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": 255, + "referenced_widgets": [ + "3859d91a1623426e85e9c43e26dba780", + "271f027241d543d38ea4c444244d106b", + "49eb6fd8239b4b629af0e97b72e30568" + ] + }, + "id": "zuSYbQTqC7Vn", + "outputId": "c4241980-8c4c-4590-fa46-bdb76a55b9b2" + }, + "source": [ + "df_lda = assign_model(rp)\n", + "df_lda.head()" + ], + "id": "zuSYbQTqC7Vn", + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titlepostTopic_0Topic_1Topic_2Topic_3Topic_4Topic_5Dominant_Topic
0any good military text-based rpg?guy use play game call basically clone call tr...4.082483-1.632993e+002.980232e-081.490116e-071.632993e+00-3.265986Topic 0
1FC 6 Defeat Admiral Benitez BROKENtry fall trough floor break video game wall se...0.8164971.632993e+00-8.164966e-01-1.632993e+00-5.960464e-08-0.816496Topic 1
2Games with great sound designappreciate good sound right game excellent sou...6.1237245.307228e+00-4.082479e-01-1.224745e+00-6.123724e+00-4.490731Topic 0
3I need a game recommendationbore tear thing reading novel exhaust read nov...0.8164971.192093e-07-2.449490e+004.082483e+00-7.748604e-072.449490Topic 3
4Why did Valve made that terrible card game?valve usually good job private corporation lis...5.307228-4.490731e+00-4.490731e+00-4.082480e-013.674234e+002.857738Topic 0
\n", + "
" + ], + "text/plain": [ + " title ... Dominant_Topic\n", + "0 any good military text-based rpg? ... Topic 0\n", + "1 FC 6 Defeat Admiral Benitez BROKEN ... Topic 1\n", + "2 Games with great sound design ... Topic 0\n", + "3 I need a game recommendation ... Topic 3\n", + "4 Why did Valve made that terrible card game? ... Topic 0\n", + "\n", + "[5 rows x 9 columns]" + ] + }, + "metadata": {}, + "execution_count": 35 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "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": 542 + }, + "id": "CGCPLIG0C7S4", + "outputId": "53093aa0-6fb7-4cb5-da67-59626426f78c" + }, + "source": [ + "plot_model(rp, plot='topic_distribution',topic_num = 4)" + ], + "id": "CGCPLIG0C7S4", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "textposition": "auto", + "hovertemplate": "Topic=%{x}
Documents=%{y}
Keyword=%{customdata[0]}", + "showlegend": false, + "legendgroup": "", + "name": "", + "yaxis": "y", + "customdata": [ + [ + "N, A" + ], + [ + "N, A" + ], + [ + "N, A" + ], + [ + "N, A" + ], + [ + "N, A" + ], + [ + "N, A" + ] + ], + "y": [ + 357, + 493, + 133, + 190, + 166, + 313 + ], + "hoverlabel": { + "namelength": 0 + }, + "offsetgroup": "", + "xaxis": "x", + "marker": { + "color": "#636efa" + }, + "x": [ + "Topic 0", + "Topic 1", + "Topic 2", + "Topic 3", + "Topic 4", + "Topic 5" + ], + "alignmentgroup": "True", + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "yaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "x", + "title": { + "text": "Documents" + } + }, + "title": { + "text": "Document Distribution by Topics" + }, + "barmode": "relative", + "xaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "y", + "title": { + "text": "Topic" + } + }, + "legend": { + "tracegroupgap": 0 + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "Eua5dKEKC7NN", + "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": 542 + }, + "outputId": "25963fb4-3da5-48f4-ae8b-62e16a04b97c" + }, + "source": [ + "plot_model(rp)" + ], + "id": "Eua5dKEKC7NN", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "name": "count", + "text": "", + "y": [ + 496, + 198, + 169, + 153, + 146, + 112, + 103, + 100, + 98, + 91, + 89, + 89, + 85, + 84, + 84, + 80, + 73, + 68, + 68, + 68, + 67, + 66, + 66, + 65, + 63, + 63, + 60, + 59, + 59, + 57, + 55, + 55, + 55, + 55, + 53, + 52, + 52, + 52, + 51, + 51, + 50, + 48, + 47, + 46, + 45, + 43, + 43, + 43, + 42, + 42, + 41, + 41, + 41, + 41, + 41, + 39, + 39, + 38, + 38, + 37, + 37, + 37, + 37, + 36, + 36, + 36, + 36, + 35, + 35, + 35, + 34, + 34, + 33, + 33, + 33, + 33, + 32, + 32, + 32, + 31, + 31, + 30, + 30, + 29, + 29, + 28, + 28, + 27, + 27, + 27, + 27, + 27, + 27, + 27, + 27, + 26, + 26, + 26, + 26, + 26 + ], + "marker": { + "color": "rgba(255, 153, 51, 0.6)", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": 1 + } + }, + "x": [ + "game", + "play", + "time", + "player", + "good", + "see", + "say", + "go", + "people", + "really", + "year", + "want", + "look", + "come", + "lot", + "new", + "use", + "ball", + "shoot", + "even", + "win", + "overwatch", + "guy", + "try", + "great", + "basketball", + "may", + "work", + "take", + "fan", + "high", + "change", + "need", + "first", + "release", + "find", + "give", + "team", + "big", + "seem", + "back", + "shot", + "start", + "second", + "long", + "love", + "thing", + "right", + "content", + "point", + "experience", + "court", + "character", + "end", + "many", + "keep", + "title", + "ever", + "bad", + "pc", + "series", + "put", + "help", + "pretty", + "fun", + "story", + "sure", + "post", + "call", + "never", + "able", + "last", + "jump", + "enough", + "old", + "far", + "day", + "set", + "star", + "gameplay", + "video", + "season", + "next", + "however", + "else", + "damage", + "little", + "thank", + "issue", + "wait", + "hero", + "watch", + "arm", + "actually", + "pick", + "hand", + "interesting", + "mean", + "bit", + "offer" + ], + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "title": { + "text": "Topic 0: Top 100 words after removing stop words", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "Count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "x74HWTsCC7Au", + "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": 113 + }, + "outputId": "cd6799a7-1fe2-4f69-c04a-e7e1b3b72399" + }, + "source": [ + "rp = create_model(metric = 'confidence')\n", + "# plotting a model\n", + "plot_model(rp)" + ], + "id": "x74HWTsCC7Au", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "error", + "ename": "SystemExit", + "evalue": "ignored", + "traceback": [ + "An exception has occurred, use %tb to see the full traceback.\n", + "\u001b[0;31mSystemExit\u001b[0m\u001b[0;31m:\u001b[0m (Value Error): Model parameter Missing. Please see docstring for list of available models.\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "3hV4wpwCB2KQ", + "outputId": "476d7b3d-143f-4741-e557-0a5d3e148df6" + }, + "source": [ + "from pycaret.utils import enable_colab\n", + "enable_colab()" + ], + "id": "3hV4wpwCB2KQ", + "execution_count": null, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Colab mode enabled.\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "EH5IcAUoB2Qy" + }, + "source": [ + "" + ], + "id": "EH5IcAUoB2Qy", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "fbecb239" + }, + "source": [ + "lda = create_model('lda', num_topics = 6, multi_core = True)" + ], + "id": "fbecb239", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 289, + "referenced_widgets": [ + "748dee4c99d249dfac20be52270ac3a6", + "497556b91c3f46968a4cd5e4ebb26376", + "6b6723ce383e43ccbdfdd5f1170234b4" + ] + }, + "id": "D5lGlRov7T67", + "outputId": "3f1b3e7d-0590-4ab9-d79f-8c923bf00ac1" + }, + "source": [ + "df_lda = assign_model(lda)\n", + "df_lda.head()" + ], + "id": "D5lGlRov7T67", + "execution_count": null, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titlepostTopic_0Topic_1Topic_2Topic_3Topic_4Topic_5Dominant_TopicPerc_Dominant_Topic
0any good military text-based rpg?guy use play game call basically clone call tr...0.0054030.0054030.7216390.0054010.1994610.062693Topic 20.72
1FC 6 Defeat Admiral Benitez BROKENtry fall trough floor break video game wall se...0.3483210.0054250.2639420.0054220.3714880.005403Topic 40.37
2Games with great sound designappreciate good sound right game excellent sou...0.0023340.0023270.0023460.0023310.9883280.002334Topic 40.99
3I need a game recommendationbore tear thing reading novel exhaust read nov...0.0032880.0032940.2147670.0033570.7719720.003322Topic 40.77
4Why did Valve made that terrible card game?valve usually good job private corporation lis...0.0034910.0035010.3740570.2898640.3255930.003492Topic 20.37
\n", + "
" + ], + "text/plain": [ + " title ... Perc_Dominant_Topic\n", + "0 any good military text-based rpg? ... 0.72\n", + "1 FC 6 Defeat Admiral Benitez BROKEN ... 0.37\n", + "2 Games with great sound design ... 0.99\n", + "3 I need a game recommendation ... 0.77\n", + "4 Why did Valve made that terrible card game? ... 0.37\n", + "\n", + "[5 rows x 10 columns]" + ] + }, + "metadata": {}, + "execution_count": 16 + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "UGbogRftF3Us", + "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": 542 + }, + "outputId": "db1a1130-eaa9-425b-f05a-3a1eaed35c89" + }, + "source": [ + "plot_model(lda)" + ], + "id": "UGbogRftF3Us", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "name": "count", + "text": "", + "y": [ + 181, + 50, + 41, + 39, + 37, + 34, + 33, + 32, + 31, + 26, + 26, + 25, + 24, + 24, + 22, + 22, + 21, + 20, + 20, + 19, + 19, + 19, + 18, + 17, + 17, + 17, + 17, + 17, + 17, + 17, + 17, + 17, + 16, + 16, + 16, + 16, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 15, + 14, + 14, + 14, + 14, + 14, + 13, + 13, + 13, + 13, + 13, + 13, + 13, + 13, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 12, + 11, + 11, + 11, + 11, + 11, + 11, + 11, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 10, + 9, + 9, + 9, + 9, + 9 + ], + "marker": { + "color": "rgba(255, 153, 51, 0.6)", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": 1 + } + }, + "x": [ + "game", + "world", + "character", + "play", + "go", + "minute", + "player", + "first", + "take", + "may", + "time", + "post", + "release", + "team", + "duo", + "link", + "good", + "see", + "lot", + "seem", + "claim", + "use", + "original", + "leak", + "place", + "big", + "mumbo", + "boss", + "discussion", + "different", + "part", + "version", + "pad", + "interesting", + "back", + "come", + "fight", + "example", + "area", + "information", + "away", + "thing", + "say", + "event", + "give", + "previous", + "pilot", + "year", + "move", + "record", + "transformation", + "new", + "outcome", + "flight", + "keep", + "final", + "ability", + "note", + "switch", + "long", + "moment", + "true", + "start", + "enemy", + "reveal", + "feature", + "day", + "find", + "end", + "body", + "performance", + "village", + "work", + "however", + "element", + "individual", + "story", + "turn", + "train", + "tier", + "collect", + "action", + "control", + "large", + "level", + "environment", + "person", + "figure", + "navigate", + "name", + "fun", + "must", + "major", + "help", + "look", + "demo", + "small", + "comment", + "weapon", + "access" + ], + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "title": { + "text": "Topic 0: Top 100 words after removing stop words", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "Count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6_5X6df1GDuy", + "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": 817 + }, + "outputId": "1a660932-efa0-4712-a6ca-30b1ecc1b567" + }, + "source": [ + "plot_model(lda, plot='TSNE',topic_num = 4)\n" + ], + "id": "6_5X6df1GDuy", + "execution_count": null, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "hovertemplate": "Dominant_Topic=Topic 0
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 0", + "name": "Dominant_Topic=Topic 0", + "scene": "scene", + "y": [ + -12.952781677246094, + -9.265008926391602, + -1.9962348937988281, + 1.1324620246887207, + -9.313617706298828, + -2.966400384902954, + -0.42377904057502747, + -4.987626552581787, + -7.990823268890381, + -10.293282508850098, + -8.901086807250977, + -5.089988708496094, + -8.76640796661377, + -9.825630187988281, + -0.7284365296363831, + -2.3588905334472656, + -0.1208610087633133, + -0.6680498719215393, + -8.875167846679688, + -10.098227500915527, + -5.165051460266113, + -3.6679775714874268, + -8.189382553100586, + -3.4794704914093018, + -8.315433502197266, + -5.081899166107178, + -9.867315292358398, + -0.6267802715301514, + -8.111859321594238, + -9.030046463012695, + -7.989945888519287, + -9.8201322555542, + -8.581459045410156, + -4.721105575561523, + -12.547602653503418, + -8.047693252563477, + -9.879441261291504, + -4.947312831878662, + -8.41650676727295, + -9.547188758850098, + -12.872017860412598, + -3.1755306720733643, + -9.012837409973145, + -10.147518157958984, + -2.1606338024139404, + -4.644028186798096, + -9.4420804977417, + -9.341626167297363, + -0.6560462117195129, + -2.209754467010498, + -4.750855445861816, + -2.0319135189056396, + -8.707001686096191, + -5.019485950469971, + -9.358445167541504, + -1.004508137702942, + -8.981026649475098, + -8.303260803222656, + -0.6612658500671387, + -5.15391206741333, + 9.164607048034668, + -1.1643303632736206, + -12.955138206481934, + -5.089998245239258, + -2.154311418533325, + -9.018869400024414, + -9.20416259765625, + -9.85068130493164, + -0.45313650369644165, + -1.0323278903961182, + -0.6610111594200134, + -4.219898700714111, + -12.511974334716797, + -8.723527908325195, + -4.454864978790283, + -9.662574768066406, + -12.961454391479492, + -9.307233810424805, + -8.444659233093262, + -9.27724552154541, + -9.331500053405762, + -7.891167163848877, + -9.450432777404785, + -10.306232452392578, + -2.4901809692382812, + -8.825359344482422, + -5.071478366851807, + -1.952672004699707, + -12.96574878692627, + -8.556737899780273, + -9.690814018249512, + -8.430411338806152, + -2.6703951358795166, + -3.8741328716278076, + -4.520465850830078, + -8.612089157104492, + -4.998388767242432, + -1.9497315883636475, + -9.125262260437012, + -8.976310729980469, + -4.8658671379089355, + -3.52653431892395, + -8.193910598754883, + -9.99521541595459, + -10.20919418334961, + -3.9465644359588623, + -9.994311332702637, + -5.009219169616699, + -8.622577667236328, + -4.693032264709473, + -4.9335856437683105, + -5.1286540031433105, + -2.3254261016845703, + -0.721130907535553, + -3.874173641204834, + -7.791946887969971, + 0.46411702036857605, + -9.266939163208008, + -12.97060489654541, + -9.508197784423828, + -8.057356834411621, + -4.8297882080078125, + -4.9828033447265625, + -4.614896774291992, + -0.1401880830526352, + -8.670934677124023, + -10.082691192626953 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#636efa", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + 4.005163192749023, + -10.524211883544922, + 2.16902494430542, + 0.9575411677360535, + -9.806402206420898, + 1.6294304132461548, + -0.4298614263534546, + 0.776912271976471, + -9.84437084197998, + -9.418457984924316, + -9.302871704101562, + 0.607396125793457, + -10.360042572021484, + -9.50954818725586, + 2.451718807220459, + 1.9773129224777222, + -0.8397263884544373, + -0.22321687638759613, + -9.300808906555176, + -8.876587867736816, + 0.9932388067245483, + 1.2467352151870728, + -10.43359088897705, + 0.035721879452466965, + -10.167816162109375, + 1.0233542919158936, + -8.894033432006836, + -0.285039484500885, + -8.701147079467773, + -8.27719783782959, + -9.124424934387207, + -10.487346649169922, + -8.400928497314453, + 1.0792672634124756, + 3.5620510578155518, + -9.678669929504395, + -8.989823341369629, + 1.0994369983673096, + -8.580658912658691, + -10.11771297454834, + 3.9001362323760986, + 1.5465295314788818, + -8.588359832763672, + -8.945857048034668, + 3.379148244857788, + 0.9521083831787109, + -9.63477897644043, + -8.81656551361084, + -0.2559400498867035, + 2.074280023574829, + 0.8839775919914246, + 2.1398277282714844, + -9.3007173538208, + 0.7489042282104492, + -9.22177791595459, + 3.0197572708129883, + -9.94970417022705, + -10.30944538116455, + 2.504502058029175, + 0.6733149886131287, + -4.169354438781738, + 2.5397567749023438, + 4.012571334838867, + 0.6074055433273315, + 2.092231512069702, + -8.8831148147583, + -10.676607131958008, + -10.48531436920166, + -0.43622493743896484, + -3.120305299758911, + -0.18056240677833557, + 1.0495386123657227, + 3.5176548957824707, + -10.678808212280273, + 0.3461734354496002, + -8.431902885437012, + 4.021415710449219, + -9.877311706542969, + -9.006591796875, + -9.601370811462402, + -8.639091491699219, + -9.954442024230957, + -10.369512557983398, + -9.544438362121582, + -3.8998987674713135, + -10.127335548400879, + 0.6045056581497192, + 3.246145725250244, + 4.030675888061523, + -8.610479354858398, + -8.463576316833496, + -9.699385643005371, + -3.9626805782318115, + -0.05835040286183357, + 0.8636106848716736, + -10.677977561950684, + 0.7725920677185059, + 3.4962592124938965, + -8.344661712646484, + -9.323820114135742, + 0.832223653793335, + 0.639461874961853, + -9.239529609680176, + -10.105013847351074, + -10.031164169311523, + 0.7832326889038086, + -9.543216705322266, + 0.7654166221618652, + -9.813910484313965, + 0.8799885511398315, + 0.6796925663948059, + 1.023681879043579, + 1.991756796836853, + -0.1759418547153473, + -0.058318160474300385, + -9.390177726745605, + 0.374328076839447, + -10.766745567321777, + 4.036811828613281, + -9.399069786071777, + -9.027310371398926, + 1.0751761198043823, + 0.7814016938209534, + 0.5857635140419006, + -0.40533074736595154, + -9.600138664245605, + -9.940608978271484 + ], + "z": [ + 3.48281192779541, + -4.677858352661133, + 6.519054889678955, + -2.879561185836792, + -3.6036946773529053, + 6.918850898742676, + -3.4836602210998535, + 6.4660773277282715, + -3.3623504638671875, + -4.255382537841797, + -5.1895599365234375, + 8.019943237304688, + -3.0090575218200684, + -4.949375152587891, + 4.417812824249268, + 6.6471333503723145, + -2.012376308441162, + -3.048793077468872, + -4.2566423416137695, + -4.241632461547852, + 8.233057022094727, + 7.146076202392578, + -3.9307754039764404, + 6.894005298614502, + -3.2776455879211426, + 7.941423416137695, + -3.135773181915283, + -3.182462215423584, + -3.920243263244629, + -4.191868782043457, + -4.437646865844727, + -4.312658786773682, + -3.841066837310791, + 8.102396965026855, + 4.520339012145996, + -4.602721214294434, + -4.7824835777282715, + 7.938204765319824, + -4.479022026062012, + -4.958742141723633, + 3.770134210586548, + 7.043868064880371, + -4.72679328918457, + -3.596963405609131, + 6.107723236083984, + 8.208671569824219, + -4.192409038543701, + -4.919614791870117, + -3.122174024581909, + 6.578915119171143, + 8.373969078063965, + 6.495851039886475, + -2.7592499256134033, + 6.12293004989624, + -3.8633527755737305, + 6.063378810882568, + -4.114518165588379, + -4.597860813140869, + 4.481513023376465, + 8.276576042175293, + -2.8992176055908203, + 6.314594745635986, + 3.4571263790130615, + 8.019942283630371, + 6.57235860824585, + -2.8235785961151123, + -3.5081655979156494, + -3.7053720951080322, + -3.499161958694458, + 5.306232929229736, + -2.929199695587158, + 7.406419277191162, + 4.620612621307373, + -4.404078006744385, + 7.842209815979004, + -4.29303503036499, + 3.43179988861084, + -2.745675802230835, + -4.920750617980957, + -5.106592655181885, + -3.127736806869507, + -4.046217918395996, + -3.04595947265625, + -3.6221771240234375, + 5.759729862213135, + -5.013861179351807, + 7.9948248863220215, + 6.107810020446777, + 3.4060051441192627, + -3.2571983337402344, + -3.755143880844116, + -4.970587253570557, + 5.825579643249512, + 7.296678066253662, + 7.590246200561523, + -3.6598308086395264, + 6.39908504486084, + 6.041074275970459, + -3.552147150039673, + -3.6229913234710693, + 8.4301118850708, + 6.501100063323975, + -3.055844783782959, + -3.2520394325256348, + -3.9580330848693848, + 6.901943683624268, + -3.053615093231201, + 6.322789192199707, + -2.7845101356506348, + 7.7845988273620605, + 8.385226249694824, + 8.282880783081055, + 6.645392417907715, + -2.95045804977417, + 7.2967119216918945, + -3.89789080619812, + -2.990800619125366, + -4.028268814086914, + 3.3934707641601562, + -2.740459442138672, + -3.4646854400634766, + 7.905300617218018, + 6.518555164337158, + 8.146464347839355, + -3.1764378547668457, + -3.8112637996673584, + -4.583567142486572 + ], + "type": "scatter3d" + }, + { + "hovertemplate": "Dominant_Topic=Topic 1
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 1", + "name": "Dominant_Topic=Topic 1", + "scene": "scene", + "y": [ + -6.462655544281006, + -11.229700088500977, + -9.616451263427734, + -6.714224815368652, + -18.280542373657227, + -8.101483345031738, + -10.508583068847656, + -15.90488052368164, + -13.037765502929688, + -7.420551300048828, + -14.858417510986328, + -8.58681583404541, + -1.4121737480163574, + -4.9017839431762695, + -7.127618789672852, + -7.2080841064453125, + -9.877260208129883, + -6.361362457275391, + -11.394880294799805, + -6.500341892242432, + -6.708255290985107, + -9.014355659484863, + -13.130047798156738, + -6.469780921936035, + -7.35611629486084, + -4.052060604095459, + -16.530641555786133, + -6.773831367492676, + -19.42967987060547, + -17.939584732055664, + -8.31396198272705, + -7.130764007568359, + -12.605992317199707, + -18.29293441772461, + -8.156390190124512, + -4.696723461151123, + -10.576131820678711, + -18.583942413330078, + -5.421331882476807, + -12.981250762939453, + -13.10446834564209, + -9.732403755187988, + -10.201224327087402, + -11.527826309204102, + -12.779324531555176, + -12.202826499938965, + -8.551987648010254, + -6.393916606903076, + -14.87646770477295, + -7.442789077758789, + -8.460128784179688, + -11.280099868774414, + -6.916918754577637, + -19.903966903686523, + -6.977274417877197, + -5.074223518371582, + -6.444393634796143, + -5.131828308105469, + -16.513580322265625, + -10.10056209564209, + -6.682920455932617, + -7.2420148849487305, + -11.81998348236084, + -8.76067066192627, + -11.871598243713379, + -4.382167339324951, + -8.932537078857422, + -8.520960807800293, + -6.092708587646484, + -8.011028289794922, + -20.6965389251709, + -5.152197360992432, + -15.98464584350586, + -9.291426658630371, + -11.40774154663086, + -9.04046630859375, + -5.065189838409424, + -7.257719993591309, + -8.76870346069336, + -13.628870010375977, + -15.973136901855469, + -17.535158157348633, + -10.747777938842773, + -6.531679630279541, + -8.117925643920898, + -20.08099937438965, + -7.517739295959473, + -5.48033332824707, + -14.888849258422852, + -7.971729278564453, + -13.010653495788574, + -18.829097747802734, + -15.329902648925781, + -11.08568286895752, + -6.336945533752441, + -13.082474708557129, + -9.850034713745117, + -14.871651649475098, + -8.80119514465332, + -6.883615970611572, + -11.672725677490234, + -10.038823127746582, + -8.576881408691406, + -17.080890655517578, + -6.935293197631836, + -13.156972885131836, + -9.871028900146484, + -13.023110389709473, + -6.960381507873535, + -17.94786262512207, + -5.53361701965332, + -2.9131343364715576, + -11.070072174072266, + -17.705703735351562, + -8.904985427856445, + -17.073015213012695, + -11.20355224609375, + -7.654767990112305, + -12.190935134887695, + -18.57558250427246, + -7.83361291885376, + -13.134194374084473, + -12.601184844970703, + -7.329394817352295, + -7.18552827835083, + -13.205999374389648, + -14.024880409240723, + -14.88235855102539, + -10.857283592224121, + -4.1865763664245605, + -5.255296230316162, + -6.717000484466553, + -6.112293243408203, + -7.7782158851623535, + -18.8385066986084, + -11.199028968811035, + -6.488353729248047, + -6.527894973754883, + -7.557707786560059, + -13.18189525604248, + -15.916121482849121, + -11.467530250549316, + -18.863117218017578, + -8.849895477294922, + -6.306185722351074, + -1.428100824356079, + -9.667990684509277, + -20.677988052368164, + -15.407093048095703, + -9.153739929199219, + -6.45606803894043, + -3.484182834625244, + -20.458223342895508, + -9.228296279907227, + -5.905689716339111, + -6.218214511871338, + -16.510282516479492, + -5.046278476715088, + -5.036760330200195, + -15.365132331848145, + -11.710701942443848, + -13.105620384216309, + -9.584549903869629, + -15.9382963180542, + -7.0127739906311035, + -5.6725873947143555, + -10.978076934814453, + -7.339437961578369, + -13.659682273864746, + -12.600266456604004, + -14.060420989990234, + -16.544591903686523, + -20.12908172607422, + -15.466167449951172, + -6.307571887969971, + -12.209296226501465, + -12.200361251831055, + -11.413475036621094, + -4.591883182525635, + -13.145974159240723, + -5.039709568023682, + -7.519472599029541, + -6.821278095245361, + -10.989238739013672, + -20.296009063720703, + -6.507477283477783, + -7.545660495758057, + -5.759968280792236, + -7.063140392303467, + -8.091937065124512, + -7.922353744506836, + -4.099131107330322, + -19.4242000579834, + -8.300346374511719, + -4.53626012802124, + -8.608624458312988, + -5.738010406494141, + -5.775628566741943, + -9.478124618530273, + -19.086750030517578, + -17.932165145874023, + -17.0373592376709, + -8.693238258361816, + -11.432021141052246, + -6.42456579208374, + -7.843025207519531, + -16.532209396362305, + -8.645051002502441, + -2.5817816257476807, + -6.184803485870361, + -5.88800573348999, + -14.873738288879395, + -14.04096508026123, + -7.264050006866455, + -7.351685523986816, + -10.947064399719238, + -13.116612434387207, + -14.715849876403809, + -6.211936950683594, + -8.144715309143066, + -10.525300025939941, + -11.591440200805664, + -10.988372802734375, + -11.413501739501953, + -7.364113807678223, + -13.270759582519531, + -17.498016357421875, + -7.079901218414307, + -5.253983974456787, + -7.066201686859131, + -20.459186553955078, + -13.135748863220215, + -6.310663223266602, + -19.71491050720215, + -4.6783671379089355, + -4.883981704711914, + -8.473592758178711, + -14.892395973205566, + -8.488570213317871, + -19.2756404876709, + -11.455482482910156, + -13.024247169494629, + -11.832039833068848, + -7.540131568908691, + -4.5958380699157715, + -8.22632122039795, + -6.321094036102295, + -7.067474365234375, + -14.924890518188477, + -5.770839214324951, + -20.383731842041016, + -9.870871543884277, + -17.541067123413086, + -5.20555305480957, + -20.24473762512207, + -17.953472137451172, + -7.4618635177612305, + -6.052487850189209, + -17.122173309326172, + -18.846731185913086, + -12.597278594970703, + -5.307808876037598 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#EF553B", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + 10.989288330078125, + 3.5383687019348145, + 8.835521697998047, + -0.48971307277679443, + 4.386814117431641, + 9.644369125366211, + 8.33525276184082, + 3.9575631618499756, + 4.330314636230469, + 5.346001625061035, + 4.1340651512146, + 9.327264785766602, + 5.404767036437988, + 11.406033515930176, + -0.14885450899600983, + 3.3696494102478027, + 8.656566619873047, + 8.948014259338379, + 7.569489479064941, + 10.619246482849121, + 10.15321159362793, + 4.766699314117432, + 4.489662170410156, + 7.520814895629883, + -0.025302493944764137, + 2.0628292560577393, + 3.9798927307128906, + -0.4211611747741699, + 4.559378147125244, + 4.258010387420654, + 8.954851150512695, + 10.605847358703613, + 4.674160480499268, + 4.377323627471924, + 3.415224075317383, + 1.4068502187728882, + 8.287837982177734, + 4.409867286682129, + 6.389725208282471, + 4.065240859985352, + 4.498652458190918, + 8.733686447143555, + 3.731566905975342, + 3.5810129642486572, + 4.692034721374512, + 4.7313055992126465, + 4.828366756439209, + 3.6500673294067383, + 4.116653919219971, + 5.477675914764404, + 4.8277177810668945, + 7.737870693206787, + 10.5200777053833, + 4.535388946533203, + 5.485777378082275, + 9.663213729858398, + 10.934670448303223, + 10.994153022766113, + 3.9690637588500977, + 8.585455894470215, + 10.36082649230957, + 3.1742451190948486, + 4.836338520050049, + 9.31029224395752, + 6.809289455413818, + 11.577412605285645, + 3.4956493377685547, + 9.555265426635742, + 9.172775268554688, + 9.988778114318848, + 3.9682822227478027, + 11.418203353881836, + 3.9402565956115723, + 3.517580986022949, + 5.045919418334961, + 3.5488619804382324, + 0.6954135298728943, + 8.70474624633789, + 4.8534159660339355, + 4.500385284423828, + 3.943787097930908, + 4.158008575439453, + 8.160359382629395, + 10.057092666625977, + 4.515059947967529, + 4.468394756317139, + 9.884308815002441, + 11.21107292175293, + 4.110511779785156, + 8.703458786010742, + 4.1569743156433105, + 4.504095077514648, + 3.960230827331543, + 7.915261268615723, + 6.900225639343262, + 4.4891886711120605, + 4.532486915588379, + 4.130415439605713, + 4.7300519943237305, + 10.594128608703613, + 7.251425743103027, + 3.8277671337127686, + 9.153843879699707, + 4.0612406730651855, + 10.192708015441895, + 4.576289176940918, + 8.665103912353516, + 4.575422763824463, + 2.9423935413360596, + 4.267709732055664, + 10.040332794189453, + 8.646883010864258, + 7.947142124176025, + 5.53791618347168, + 3.4730119705200195, + 4.0619306564331055, + 7.832126140594482, + 3.215646743774414, + 4.730772972106934, + 4.402450084686279, + 9.842140197753906, + 4.570900917053223, + 4.674465656280518, + 10.123580932617188, + 5.620118141174316, + 4.602096080780029, + 4.417965888977051, + 4.132887840270996, + 8.083226203918457, + 10.986536026000977, + 10.836410522460938, + 3.028876543045044, + 9.148174285888672, + 3.301295757293701, + 4.513706207275391, + 7.831212520599365, + 7.117178916931152, + -0.5911513566970825, + 9.860715866088867, + 4.599190711975098, + 3.9076642990112305, + 3.5364599227905273, + 4.515500545501709, + 9.338445663452148, + 10.901631355285645, + 5.445764541625977, + 4.4499406814575195, + 4.017000198364258, + 3.8639159202575684, + 3.5275657176971436, + 7.258242130279541, + 9.399127006530762, + 4.257205963134766, + 8.896883964538574, + 5.5217814445495605, + 6.717564582824707, + 3.9586620330810547, + 5.349241733551025, + 0.7237123250961304, + 4.001242160797119, + 4.934438228607178, + 4.592708587646484, + 4.2179036140441895, + 3.943378210067749, + -0.21460214257240295, + 6.394946575164795, + 8.003296852111816, + 3.1025755405426025, + 4.4957756996154785, + 4.67498779296875, + 4.4076714515686035, + 3.970686435699463, + 4.450677871704102, + 3.9610989093780518, + 5.7815070152282715, + 4.732235908508301, + 4.733911991119385, + 5.042809009552002, + 11.448192596435547, + 4.579807758331299, + 10.561432838439941, + 0.07080453634262085, + 10.53741455078125, + 3.5857861042022705, + 4.364221096038818, + -0.6975098252296448, + 0.07975075393915176, + 11.165270805358887, + -0.22954145073890686, + 3.3667314052581787, + 3.3293299674987793, + 1.7978495359420776, + 4.558454990386963, + 9.519312858581543, + 11.472537994384766, + 4.833909034729004, + 0.01170550286769867, + 9.308119773864746, + 3.5448617935180664, + 4.491261959075928, + 4.284236907958984, + 4.063962936401367, + 3.4899892807006836, + 3.538360118865967, + 5.792293548583984, + 5.18149995803833, + 3.968930244445801, + 4.801449298858643, + 8.397482872009277, + -0.5114725828170776, + 10.089115142822266, + 4.123409748077393, + 4.4125237464904785, + 6.467622756958008, + 6.5152692794799805, + 5.436863422393799, + 4.641655445098877, + 3.701991558074951, + 6.6009650230407715, + 3.3723762035369873, + 3.5370585918426514, + 3.616258144378662, + 3.5522620677948, + 5.043054580688477, + 10.52750015258789, + 4.614506721496582, + 4.141021251678467, + -0.21052959561347961, + 5.344884872436523, + 5.5853681564331055, + 4.256015300750732, + 4.6236772537231445, + -0.8989968299865723, + 4.549543857574463, + 4.328902244567871, + 11.241133689880371, + 4.95287561416626, + 4.112515449523926, + 3.41546630859375, + 4.556414604187012, + 3.5197315216064453, + 4.721005439758301, + 4.83258581161499, + 5.345643043518066, + 11.504249572753906, + 5.0971503257751465, + 6.8036580085754395, + 5.506176948547363, + 5.704631805419922, + 11.14995002746582, + 4.312714099884033, + 3.996443510055542, + 4.1584672927856445, + 4.985383033752441, + 4.396529674530029, + 4.2752766609191895, + 5.300705909729004, + 11.028555870056152, + 2.9386987686157227, + 4.546566486358643, + 4.674901962280273, + 0.41454407572746277 + ], + "z": [ + -3.2912588119506836, + -3.6887047290802, + -3.6858749389648438, + -0.7515668869018555, + -4.36586856842041, + -4.972332000732422, + -3.473947525024414, + -3.8650293350219727, + 2.453580856323242, + 1.1192973852157593, + -3.4134340286254883, + -3.791236639022827, + 5.051283359527588, + -2.7174084186553955, + -0.7634555697441101, + -5.244801044464111, + -3.658451557159424, + -5.291637897491455, + -3.1280581951141357, + -3.4179670810699463, + -3.566800594329834, + -0.24072837829589844, + 1.7177215814590454, + -4.121260643005371, + -0.7240394949913025, + -2.617637872695923, + -3.9571897983551025, + -0.7668964862823486, + -4.417638778686523, + -4.228200912475586, + -3.8666019439697266, + -3.4091484546661377, + -2.291288375854492, + -4.377625465393066, + -4.939026355743408, + -3.2971785068511963, + -3.4507548809051514, + -4.246164798736572, + -4.251655578613281, + 3.300096035003662, + 1.7174975872039795, + -3.6911611557006836, + -0.9699397683143616, + -3.5645172595977783, + 0.3345537483692169, + -1.9640581607818604, + -0.16775019466876984, + -3.5864810943603516, + -3.4249069690704346, + 0.883827805519104, + -0.33947914838790894, + -3.201796054840088, + -3.45719051361084, + -4.460992813110352, + 1.8598719835281372, + -1.6118913888931274, + -3.305870532989502, + -2.9410369396209717, + -3.9546892642974854, + -3.5887084007263184, + -3.499711513519287, + -5.366365909576416, + -1.3490201234817505, + -3.7064602375030518, + -2.8283002376556396, + -2.3347420692443848, + -4.572608947753906, + -3.6344211101531982, + -5.321800231933594, + -3.5085151195526123, + -4.832768440246582, + -2.834249496459961, + -3.724668025970459, + -4.402001857757568, + -0.5376104712486267, + -4.442753314971924, + -2.527665138244629, + -5.047008991241455, + -0.040272001177072525, + -2.804842710494995, + -3.7027482986450195, + -4.177641868591309, + -3.384509801864624, + -3.5803427696228027, + -1.6304351091384888, + -4.44132137298584, + -3.685056686401367, + -3.009782075881958, + -3.4216392040252686, + -4.589900016784668, + 3.0067694187164307, + -4.446275234222412, + -3.746182680130005, + -3.273932933807373, + -4.269866943359375, + 1.7890071868896484, + -0.620547890663147, + -3.416621208190918, + -0.11982422322034836, + -3.443215847015381, + -3.020418882369995, + -0.862437903881073, + -3.9439830780029297, + -4.081021785736084, + -3.5690300464630127, + 1.237075924873352, + -3.6589934825897217, + 1.4564433097839355, + -5.446324825286865, + -4.206449031829834, + -3.9446756839752197, + -2.785121202468872, + -3.290192127227783, + -4.332751274108887, + -4.626539707183838, + -4.08355188369751, + -3.2419517040252686, + -5.253935813903809, + -1.955122709274292, + -4.226480960845947, + -3.6496167182922363, + 1.3114482164382935, + -2.2892966270446777, + -3.576113224029541, + 1.0331553220748901, + 0.8374027609825134, + -2.9706928730010986, + -3.420227527618408, + -3.3458008766174316, + -2.6665923595428467, + -3.029552936553955, + -5.553778648376465, + -5.317872524261475, + -5.140917778015137, + -4.439032077789307, + -3.2410929203033447, + -4.234833717346191, + -0.7721056938171387, + -3.6933693885803223, + 0.9591494798660278, + -3.840660572052002, + -3.635347604751587, + -4.2981743812561035, + -3.6759963035583496, + -3.297968626022339, + 5.033719062805176, + -0.5237236618995667, + -4.803287982940674, + -3.6116676330566406, + -4.436813831329346, + -4.2016472816467285, + -2.795149803161621, + -4.643678665161133, + -3.831968307495117, + -4.4863972663879395, + 1.027747631072998, + -3.958949565887451, + -4.362058639526367, + -2.6496500968933105, + -3.760770320892334, + 0.10068681836128235, + -2.557584762573242, + -0.5608092546463013, + -3.8425769805908203, + -0.784109354019165, + -4.2947001457214355, + -3.312411069869995, + -5.3938798904418945, + -2.816570997238159, + -2.28882098197937, + -2.989323616027832, + -3.958867311477661, + -4.463066577911377, + -3.466505527496338, + -4.506810665130615, + -1.9684590101242065, + -1.959258794784546, + -0.5451006889343262, + -2.521963119506836, + 1.2254160642623901, + -2.9881339073181152, + -0.7009212374687195, + -3.4627883434295654, + -3.6698923110961914, + -4.544451713562012, + -0.7155734300613403, + -0.6985588669776917, + -3.102769613265991, + -0.7446293830871582, + -5.010414123535156, + -5.086806774139404, + -2.4583492279052734, + -4.418124675750732, + -4.691305637359619, + -2.4769833087921143, + -0.0026491335593163967, + -1.6477969884872437, + -1.8392471075057983, + -4.320047855377197, + -4.290703296661377, + -4.2230000495910645, + -4.083929061889648, + -4.665800094604492, + -3.6399099826812744, + -4.263438701629639, + 0.5761491060256958, + -3.9579098224639893, + -0.009425932541489601, + -2.705177068710327, + -1.0011937618255615, + -3.4599194526672363, + -3.419842004776001, + -2.981882333755493, + 0.04318392649292946, + -0.1138475313782692, + -0.0714268833398819, + -0.04869090020656586, + -2.330095052719116, + -4.307064533233643, + -4.989575386047363, + -3.9069557189941406, + -3.5090928077697754, + -3.730750799179077, + -0.5431572794914246, + -3.422685384750366, + 0.06949661672115326, + -4.174488544464111, + -0.7483767867088318, + -4.43105411529541, + 1.3470799922943115, + -4.643558025360107, + 0.6743637919425964, + -0.6721499562263489, + -4.391198635101318, + -3.9297232627868652, + -2.753432273864746, + 0.01812969334423542, + -3.430293321609497, + -4.854551315307617, + -4.4212799072265625, + -3.6605093479156494, + 1.059955358505249, + -1.3708115816116333, + 0.9680743217468262, + -2.507869005203247, + 0.1867327094078064, + -4.37939977645874, + 1.585097312927246, + -3.6565473079681396, + -3.111450672149658, + -4.610223293304443, + -0.7419543862342834, + -4.180024147033691, + -4.523252964019775, + -4.517604827880859, + -4.225320816040039, + 1.241658091545105, + -3.2127685546875, + -4.650049209594727, + -4.349940776824951, + -2.2858095169067383, + -2.1867690086364746 + ], + "type": "scatter3d" + }, + { + "hovertemplate": "Dominant_Topic=Topic 2
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 2", + "name": "Dominant_Topic=Topic 2", + "scene": "scene", + "y": [ + -3.2375452518463135, + -0.356904536485672, + -2.9072165489196777, + -1.2503623962402344, + 11.330135345458984, + -2.393638849258423, + 2.9124345779418945, + 1.2077627182006836, + 8.920845031738281, + 6.883256435394287, + -1.445576786994934, + 4.156599521636963, + 8.928717613220215, + 9.564469337463379, + 9.977560043334961, + 5.873775482177734, + -0.6887364387512207, + 10.57140827178955, + 3.9367706775665283, + 3.626600980758667, + 2.610578775405884, + -4.253471374511719, + 9.83118724822998, + 3.9478940963745117, + 7.087063789367676, + 4.334781646728516, + 4.221623420715332, + 6.624031066894531, + -0.8894284963607788, + 4.697917461395264, + -0.2360605150461197, + 8.971238136291504, + 9.479426383972168, + -0.6372182965278625, + 5.205533981323242, + 6.611804962158203, + 10.066231727600098, + 3.998826265335083, + 10.827693939208984, + 5.388146877288818, + 4.057868957519531, + 9.717595100402832, + 2.469006061553955, + 5.335699558258057, + 8.38245677947998, + 10.117535591125488, + -3.132675886154175, + 5.315749168395996, + 7.7365241050720215, + 9.207907676696777, + 6.2435221672058105, + 4.411871433258057, + 4.556830883026123, + 5.6327385902404785, + -1.362877607345581, + 4.374614238739014, + 8.4940767288208, + 0.5310972332954407, + 3.627699851989746, + -3.8625667095184326, + 6.489010334014893, + 2.453325033187866, + 5.852274417877197, + 6.81020450592041, + 9.83349609375, + 0.0570969358086586, + 5.654759407043457, + -2.5026166439056396, + 9.677698135375977, + 7.079924583435059, + 5.9729228019714355, + -3.54892897605896, + 8.379606246948242, + -0.5511313080787659, + 11.924509048461914, + 7.385992527008057, + 6.778958320617676, + 1.8011528253555298, + 3.8579001426696777, + 8.062849998474121, + 7.215804576873779, + 3.143826484680176, + 10.119112968444824, + -1.5648548603057861, + 10.128992080688477, + -1.2609200477600098, + 4.677387714385986, + 8.613125801086426, + 3.947540283203125, + -0.4022461771965027, + 4.259779930114746, + 9.859162330627441, + 8.226432800292969, + 3.455127000808716, + 7.778365612030029, + 6.045406341552734, + 6.7132134437561035, + 3.861513614654541, + -0.7040325403213501, + -2.0253560543060303, + 9.644843101501465, + 4.559953689575195, + 3.7881784439086914, + -0.2442360371351242, + 5.663475036621094, + 2.6400864124298096, + -0.6820684671401978, + 5.960849285125732, + 10.003963470458984, + 9.65802001953125, + 4.422239780426025, + -3.4966635704040527, + 8.969636917114258, + -2.765913963317871, + -0.35057076811790466, + -0.3942013382911682, + -0.16541989147663116, + 10.920296669006348, + 10.573014259338379, + 8.18728256225586, + 7.739440441131592, + 0.35533949732780457, + 4.064001560211182, + -0.7526300549507141, + 10.324718475341797, + -0.8113937973976135, + 8.60717487335205, + 0.5508105158805847, + 0.6867920756340027, + 9.766944885253906, + 11.374137878417969, + 6.970937728881836, + 10.30878734588623, + 1.164376974105835, + -0.0953620970249176, + 4.112170219421387, + 11.007166862487793, + -0.5965978503227234, + -0.998328447341919, + -1.6921383142471313, + 11.2046480178833, + -1.004204273223877, + 6.452266216278076, + -1.5840110778808594, + 3.6764369010925293, + 6.637798309326172, + 3.5783309936523438, + 7.737831115722656, + -2.173720598220825, + 9.666213035583496, + 3.544172525405884, + 6.0263285636901855, + -0.6581058502197266, + -0.27407047152519226, + 9.68248462677002, + -0.3753349184989929, + 6.903289318084717, + 10.946961402893066, + -2.1267848014831543, + -2.5229904651641846, + 5.189114093780518, + 8.682977676391602, + 3.5449624061584473, + 9.147027015686035, + 11.161883354187012, + 8.73605728149414, + 10.843392372131348, + 9.384649276733398, + 11.245293617248535, + 5.300323486328125, + 9.411684036254883, + -0.222570538520813, + 7.125710487365723, + 5.52353572845459, + 7.253862380981445, + 6.345576286315918, + 4.0568342208862305, + 10.615694046020508, + 0.19627150893211365, + 5.197285175323486, + -1.223047137260437, + 5.533382892608643, + 10.874253273010254, + 5.434872627258301, + 8.297480583190918, + 3.6423277854919434, + -3.3259150981903076, + -3.821211576461792, + 11.147292137145996, + -0.3751070201396942, + -2.3423666954040527, + -2.136847972869873, + 6.101501941680908, + 4.688867568969727, + 10.11872386932373, + 4.024632930755615, + 0.2891911566257477, + 10.180658340454102, + 6.475926876068115, + 11.011672019958496, + 10.571212768554688, + 6.688497543334961, + 9.82744026184082, + 9.943395614624023, + 8.291472434997559, + -2.9795968532562256, + 3.2011168003082275, + 7.148099899291992, + 9.763972282409668, + 9.216607093811035, + 7.3005571365356445, + 0.3071296513080597, + 9.990283012390137, + 10.128679275512695, + 6.318672180175781, + 10.896778106689453, + 9.479310035705566, + 9.551345825195312, + 5.566145896911621, + 9.423198699951172, + 6.341798782348633, + 8.291658401489258, + 6.214832782745361, + 9.55054759979248, + 11.189597129821777, + 6.843471527099609, + 10.522007942199707, + 4.120150566101074, + 9.665153503417969, + 5.083588123321533, + 6.1157941818237305, + -1.7786508798599243, + 9.639674186706543, + 2.7940585613250732, + 9.684858322143555, + 9.692739486694336, + 6.337932586669922, + -1.8886302709579468, + -0.8495186567306519, + 10.921041488647461, + -3.9115264415740967, + -2.7924656867980957, + -1.2394312620162964, + 8.684661865234375, + -2.183842658996582, + 10.875635147094727, + 0.319193571805954, + 3.5451197624206543, + 10.316949844360352, + 8.140573501586914, + 3.4806222915649414, + 6.613600254058838, + -1.8162671327590942, + 9.222426414489746, + 9.705159187316895, + 9.79148006439209, + -1.1531548500061035, + 9.685380935668945, + 2.1493802070617676, + 6.907106876373291, + 10.237078666687012, + -0.5663512349128723, + 9.293196678161621, + -0.8977519869804382, + 3.4090218544006348, + -3.403465747833252, + 11.291523933410645, + 3.545163869857788, + 5.63596248626709, + -1.7228291034698486, + 9.691301345825195, + 7.528981685638428, + 8.117897987365723, + 3.575270175933838, + 8.681304931640625, + -3.316037654876709, + 8.333958625793457, + 9.399081230163574, + -2.603731393814087, + 6.344676971435547, + -0.4605970084667206, + 3.6259708404541016, + 9.986661911010742, + 9.241171836853027, + 0.6219559907913208, + 10.716981887817383, + 2.4619054794311523, + -0.7555057406425476, + 10.33286190032959, + 6.6079487800598145, + -3.33402943611145, + 5.730962753295898, + 5.88670015335083, + 7.396848678588867, + 10.336518287658691, + -0.3714200258255005, + 10.68535041809082, + -0.3519291281700134, + -0.7922941446304321, + 6.09899377822876, + 2.2155017852783203, + 3.5448381900787354, + 11.082029342651367, + -2.303201675415039, + -1.6462451219558716, + 3.453768253326416, + 7.060863494873047, + 8.286398887634277, + 10.52436637878418, + 9.538984298706055, + 1.9297537803649902, + 4.1933817863464355, + 6.871485233306885, + 1.35844087600708, + 2.2513439655303955, + 0.5855870842933655, + 10.41201400756836, + 5.019503116607666, + 6.129405975341797, + -0.7258642315864563, + 10.129677772521973, + 11.283583641052246, + 10.127628326416016, + -4.34144926071167, + 9.48345947265625, + -2.6759374141693115, + -1.2852612733840942, + 6.344582557678223, + -3.5515449047088623, + 9.548291206359863, + 3.517134189605713, + 7.105941295623779, + 9.719827651977539, + -0.42651212215423584, + -2.663205623626709, + -2.2856621742248535, + -2.5733695030212402, + 0.3938595652580261, + 1.6098263263702393, + 6.886116981506348, + 8.31312370300293, + 2.8313727378845215, + 7.723470211029053, + 1.3800004720687866, + 5.266129493713379, + 10.800165176391602, + 4.899027347564697, + 3.8883512020111084, + 1.4381558895111084, + 7.068641185760498, + -0.4982309639453888, + 10.331140518188477, + 5.003243446350098, + 9.87307071685791, + 9.685288429260254, + 10.12491226196289, + 6.553941249847412, + 5.047473907470703, + 8.96235179901123, + 4.485458850860596, + 9.730243682861328, + 5.835160732269287, + 3.721101760864258, + 3.7853891849517822, + 6.935836315155029, + 8.608284950256348, + 2.060910940170288, + 5.063776969909668, + 5.003772258758545, + 5.936783790588379, + 7.728592395782471, + 10.468485832214355, + 6.807417392730713, + 2.6340222358703613, + 1.962807297706604, + 7.15915060043335, + 6.721656799316406, + 7.09773588180542, + 6.668390274047852, + 4.314992904663086, + 7.338710784912109, + 4.166985511779785, + 3.708634376525879, + 5.099975109100342, + 5.858352184295654, + 6.767480373382568, + 6.150874137878418, + 9.906017303466797, + -0.6325511336326599, + -2.225229263305664, + 1.3290443420410156, + 7.54355001449585, + 1.0052697658538818, + 6.4229631423950195, + 3.2846243381500244, + 9.566025733947754, + 6.76565408706665, + 10.143692970275879, + 8.798800468444824, + 2.4098827838897705, + 5.819385528564453, + 4.75313138961792, + -0.06526639312505722, + 0.9138094186782837, + 5.33521032333374, + 8.431469917297363, + -2.1795449256896973, + 1.7072712182998657, + 5.35109806060791, + 7.564549446105957, + 9.397518157958984, + 9.833413124084473, + 9.854240417480469, + -2.078836679458618, + 5.814487934112549, + 3.6633710861206055, + 4.148449897766113, + 5.794688701629639, + 7.738442897796631, + 9.839179039001465, + 4.033998966217041, + 10.073952674865723, + 9.213696479797363, + 9.547981262207031, + 7.701108455657959, + 2.523695468902588, + 10.23765754699707, + -1.8931087255477905, + 8.680074691772461, + 6.4884562492370605, + 0.2572881877422333, + 9.690401077270508, + 9.711969375610352, + 10.882403373718262, + 9.02766227722168, + 7.280882835388184, + 9.37926197052002, + 2.5248732566833496, + 4.273128986358643, + 2.169219732284546, + 3.6328959465026855, + 8.28986930847168, + 6.275667190551758, + 3.8952369689941406, + 10.521750450134277, + -0.9784331917762756, + -0.14461685717105865, + 10.324381828308105, + 9.410635948181152, + 2.516227960586548, + 9.686458587646484, + 10.231550216674805, + 10.520220756530762, + 3.8995754718780518, + 8.292428016662598, + 10.123045921325684, + 4.192159175872803, + 9.993797302246094, + 8.684449195861816, + 5.196208477020264, + 3.1998589038848877, + 6.058115005493164, + 7.003643035888672, + 7.73614501953125, + 11.072078704833984, + 8.674714088439941, + 10.611018180847168, + 9.037873268127441, + 2.1495375633239746, + 6.510381698608398, + -0.3070071041584015, + 4.610767841339111, + 4.446377754211426, + 6.697004795074463, + 10.234550476074219, + -3.2832014560699463, + 2.2997682094573975, + 5.694278717041016, + 5.738977909088135, + 9.769250869750977, + 6.248685836791992, + 7.103954792022705, + 10.830297470092773, + 2.6023683547973633, + 4.21856164932251, + 3.467777967453003, + 4.73458194732666, + 4.473443031311035, + 6.748904705047607, + 1.5224735736846924, + 6.452540397644043, + 9.182619094848633, + 2.197718858718872, + 10.9630765914917, + 10.405942916870117, + 1.9851744174957275, + 9.670758247375488, + 4.14633321762085, + 10.12525463104248, + 4.197518348693848, + 6.043187618255615, + 3.9359333515167236, + 5.743913650512695, + 10.863933563232422, + 2.442713499069214, + 9.636205673217773, + -0.025625351816415787, + 6.073031902313232, + 9.465500831604004, + 8.593950271606445, + 8.679689407348633, + 5.804584980010986, + 9.402031898498535, + 9.493470191955566, + 6.686851978302002, + 6.382898330688477, + 6.023836612701416, + 3.430203676223755, + 9.876626014709473, + 0.4003569185733795, + 0.41908907890319824, + 9.696157455444336, + 1.031868815422058, + 7.746220111846924, + 9.046204566955566, + 2.6487224102020264, + 5.9470534324646, + 9.046241760253906, + 6.565003871917725, + 6.227074146270752, + 7.678930282592773, + 11.129388809204102, + 10.784211158752441, + 5.80719518661499, + 6.136362552642822, + 3.416893243789673, + 11.313156127929688, + 10.942351341247559, + 5.624959945678711, + 2.185591697692871, + 10.747008323669434, + 8.221894264221191, + 10.954505920410156, + 3.499580144882202, + 11.954872131347656, + 9.545243263244629, + 3.1443231105804443, + 9.73743724822998, + 3.1179440021514893, + 10.785213470458984, + 4.373232841491699, + 2.3410322666168213, + 10.784340858459473, + 4.548933506011963, + 3.9394497871398926, + 10.960987091064453, + 0.21255646646022797, + 6.008898735046387 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#00cc96", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + 9.017034530639648, + 10.698357582092285, + 9.261704444885254, + 6.382248878479004, + 19.100372314453125, + 11.767654418945312, + 4.921090602874756, + 6.435094356536865, + -1.3023115396499634, + 9.096646308898926, + 7.74360466003418, + 5.636638641357422, + -0.001018347917124629, + -0.07750634849071503, + -0.4681428372859955, + -0.42603135108947754, + 5.829414367675781, + 15.901217460632324, + 4.938028335571289, + 5.146066188812256, + 2.379988670349121, + 8.441488265991211, + -0.7163697481155396, + 3.106294631958008, + 8.47876262664795, + 4.5394182205200195, + 6.638854503631592, + 1.1515154838562012, + 11.420130729675293, + 7.225496292114258, + 10.795927047729492, + 7.579161167144775, + 10.418157577514648, + 5.835324287414551, + 2.3224194049835205, + 0.44736501574516296, + -1.4549365043640137, + 6.044724941253662, + 17.479564666748047, + -3.277019500732422, + 6.249102592468262, + 1.6602221727371216, + -3.3187129497528076, + 7.750433921813965, + 9.367575645446777, + 13.443087577819824, + 12.325284004211426, + -2.0028512477874756, + 5.470739364624023, + 8.224953651428223, + 8.24354362487793, + 6.911986351013184, + 3.7284998893737793, + 4.244482517242432, + 8.28172492980957, + 4.5234150886535645, + 9.471312522888184, + 6.578701496124268, + -2.979429006576538, + 8.646029472351074, + 0.795177161693573, + -3.421473264694214, + -0.7940221428871155, + 8.509598731994629, + 12.03762149810791, + 3.7590601444244385, + -1.3385370969772339, + 11.77787971496582, + 11.230215072631836, + 6.429218292236328, + 0.8731151819229126, + 8.77158260345459, + 9.372142791748047, + 11.54132080078125, + 10.758429527282715, + 8.866961479187012, + 9.072935104370117, + 3.8516147136688232, + -3.8658699989318848, + 9.031018257141113, + 7.4802656173706055, + 6.3492751121521, + -1.2672302722930908, + 11.840840339660645, + 13.505294799804688, + 4.889246463775635, + 7.224666595458984, + 9.567584991455078, + 8.151531219482422, + 6.221715927124023, + -2.9965362548828125, + 3.7875277996063232, + 9.228577613830566, + 5.1464314460754395, + 9.039688110351562, + 5.761746883392334, + -0.2125208079814911, + 5.360651016235352, + 6.9911885261535645, + 8.205833435058594, + 2.326817512512207, + 7.089492321014404, + 6.4442458152771, + 2.6892104148864746, + 8.031694412231445, + 2.9910309314727783, + 10.953666687011719, + 8.04986572265625, + 0.10054938495159149, + 2.7444467544555664, + 4.182570934295654, + 9.606308937072754, + 7.5660552978515625, + 11.808034896850586, + 3.023768186569214, + 11.094314575195312, + 2.6725821495056152, + 17.879722595214844, + 15.9104642868042, + -0.9969885349273682, + 5.4801740646362305, + 3.2365963459014893, + 6.247928142547607, + 7.555698394775391, + 14.53031063079834, + 11.275898933410645, + 9.55673599243164, + 10.95436954498291, + 10.828202247619629, + 2.082313299179077, + 19.204017639160156, + 5.088943004608154, + 4.326056480407715, + 4.488122463226318, + 11.066295623779297, + 5.6669721603393555, + 18.74202537536621, + 10.192011833190918, + 11.356949806213379, + 11.954090118408203, + 18.39248275756836, + 10.661725044250488, + 0.927436113357544, + 12.02357006072998, + 4.623064041137695, + 1.2196637392044067, + 5.802000999450684, + 5.44778299331665, + 11.202733993530273, + 3.2466580867767334, + 4.140802383422852, + 7.504857063293457, + 10.146554946899414, + 11.1270112991333, + 10.384624481201172, + 11.18580150604248, + 5.041808605194092, + 17.93834686279297, + 11.931768417358398, + 12.427244186401367, + 7.685499668121338, + 6.873627662658691, + 4.141379356384277, + 2.1911792755126953, + 19.437808990478516, + 0.011131593026220798, + 17.492427825927734, + 10.392328262329102, + 18.742116928100586, + 7.782682418823242, + 8.914521217346191, + 3.0872011184692383, + 4.791584014892578, + -1.5191309452056885, + 7.6199631690979, + 4.486715316772461, + 4.844884872436523, + 16.16172981262207, + 10.992030143737793, + 7.683638095855713, + 10.043810844421387, + 7.709236145019531, + 17.627765655517578, + 7.86749267578125, + 6.185155868530273, + 3.2838382720947266, + 11.241350173950195, + 8.727023124694824, + 19.408100128173828, + 11.253684043884277, + 11.646427154541016, + 11.95425796508789, + 6.29889440536499, + 7.163564682006836, + -0.6509143710136414, + 8.26646614074707, + 3.2683870792388916, + 4.196031093597412, + 8.372532844543457, + 18.185213088989258, + 15.899227142333984, + 8.671431541442871, + 12.011947631835938, + 3.9512805938720703, + 6.190014362335205, + 9.329322814941406, + 4.283473968505859, + 4.893566131591797, + 0.8863837718963623, + 8.248923301696777, + 8.49549674987793, + 10.984554290771484, + 12.811822891235352, + 13.512277603149414, + 8.245851516723633, + 17.969314575195312, + 10.415963172912598, + 9.611187934875488, + 7.855125904083252, + 0.9454662799835205, + 4.489797115325928, + 6.189063549041748, + 8.206963539123535, + 9.609929084777832, + 19.45853042602539, + 9.112431526184082, + 15.627179145812988, + 4.8800201416015625, + 11.155586242675781, + -3.0195608139038086, + 8.107025146484375, + 12.085681915283203, + 10.374946594238281, + 3.727564811706543, + 2.251371383666992, + 3.2703676223754883, + 4.492466926574707, + 11.950567245483398, + 7.537927150726318, + 17.95281219482422, + 2.0023415088653564, + 11.975380897521973, + 5.111213684082031, + 6.8798723220825195, + 8.018242835998535, + 17.613666534423828, + 10.957170486450195, + 4.141810894012451, + 4.33621072769165, + 9.160262107849121, + 5.731467247009277, + 8.459792137145996, + 12.076416969299316, + 8.26487922668457, + 11.247509956359863, + 3.5107414722442627, + 10.819428443908691, + 11.231945991516113, + -3.0882678031921387, + 4.8950886726379395, + 14.04311752319336, + 11.088611602783203, + 2.5058765411376953, + 7.398941993713379, + 4.432476997375488, + 9.374434471130371, + 19.14710807800293, + 4.141567707061768, + 4.245366096496582, + 12.086807250976562, + 1.6488384008407593, + 8.807368278503418, + 9.155817985534668, + 6.210018634796143, + 6.870862007141113, + 11.346551895141602, + 9.35147476196289, + 3.443242311477661, + 12.482738494873047, + 4.482058525085449, + 7.3448100090026855, + 4.558424949645996, + 12.79686164855957, + -1.0066719055175781, + 10.94559383392334, + 16.805221557617188, + -1.629868507385254, + 11.190954208374023, + 14.54134750366211, + 1.0753026008605957, + 11.478856086730957, + -1.1361390352249146, + -2.82319974899292, + 8.900914192199707, + 14.561409950256348, + 11.209670066833496, + 16.58711814880371, + 10.874866485595703, + 5.5582661628723145, + 8.127181053161621, + -3.501006841659546, + 4.141205787658691, + 19.388338088989258, + 8.58299446105957, + 11.337772369384766, + 5.155461311340332, + 5.030234336853027, + 6.1809515953063965, + 15.631872177124023, + 9.599005699157715, + -1.884880781173706, + 6.338307857513428, + 4.93168830871582, + 4.554290771484375, + -1.7546279430389404, + 10.951509475708008, + 14.979406356811523, + -2.5750205516815186, + 0.048258423805236816, + 5.42722749710083, + 13.484831809997559, + 18.718385696411133, + 13.476426124572754, + 8.193984985351562, + 10.443175315856934, + 12.333168983459473, + 11.69492244720459, + 4.479602813720703, + 12.017885208129883, + 9.615005493164062, + 4.60650110244751, + 4.897795677185059, + 2.15346360206604, + 2.594914197921753, + 12.180781364440918, + 12.380034446716309, + 12.276838302612305, + 10.933629989624023, + 3.212679624557495, + 8.385763168334961, + 0.23126602172851562, + -3.1392109394073486, + 5.441919803619385, + -1.5734574794769287, + -3.1679883003234863, + 18.32245635986328, + -2.6861352920532227, + 5.20702600479126, + 3.724703788757324, + 4.770897388458252, + 11.521768569946289, + 14.535568237304688, + 7.5132880210876465, + 0.7033722400665283, + 3.2459583282470703, + -0.6101602911949158, + 0.9318382740020752, + 7.466740131378174, + 7.544519901275635, + 3.782156229019165, + 10.362711906433105, + -0.962620198726654, + 6.038547515869141, + -3.9640872478485107, + 4.864231109619141, + 0.503340482711792, + -2.3515870571136475, + -2.513807535171509, + 7.5189056396484375, + -4.202415943145752, + 5.4612321853637695, + 15.322908401489258, + 8.731274604797363, + 3.4652180671691895, + -1.5895732641220093, + 7.541885852813721, + 8.648246765136719, + -0.43898698687553406, + 1.2100294828414917, + 4.312014102935791, + -0.7886989712715149, + 6.46842622756958, + 3.146327495574951, + 7.308228015899658, + -0.8069855570793152, + -3.111872911453247, + -0.14342382550239563, + -0.9357938766479492, + 2.740957021713257, + 11.804866790771484, + 3.673478603363037, + 8.541775703430176, + 2.6334145069122314, + 1.6438692808151245, + 4.026970386505127, + -0.11109138280153275, + 0.21134382486343384, + -0.8184201717376709, + 0.48940229415893555, + 3.952392578125, + -0.3661327660083771, + -2.9525563716888428, + 2.9496397972106934, + 3.4984066486358643, + -1.9640207290649414, + 9.396570205688477, + 12.246310234069824, + 3.8569893836975098, + -1.956453561782837, + 0.35568079352378845, + 8.844383239746094, + 12.036169052124023, + 0.9142453074455261, + 12.051840782165527, + -3.3359169960021973, + 4.55711030960083, + 6.7294697761535645, + -1.1606733798980713, + 5.462136268615723, + 12.066108703613281, + 4.865853309631348, + -0.1614467054605484, + 8.237298011779785, + 9.56702995300293, + 5.451265335083008, + 2.6185367107391357, + 14.045869827270508, + 7.783496856689453, + 6.868542194366455, + 0.029127882793545723, + 3.17903208732605, + 11.268265724182129, + 11.181595802307129, + 18.990116119384766, + -1.4503005743026733, + 8.758386611938477, + 10.398218154907227, + -1.6469296216964722, + -4.5887556076049805, + -3.1498138904571533, + 5.597529888153076, + 6.177043437957764, + -3.293505907058716, + 5.86248254776001, + 15.607418060302734, + -3.057739019393921, + 3.5416831970214844, + 14.527897834777832, + 8.90040111541748, + 2.2702395915985107, + 1.111704707145691, + -1.284663200378418, + 15.59753704071045, + 6.548365592956543, + 6.191133975982666, + 13.453930854797363, + -4.445191860198975, + 12.835501670837402, + 6.876514434814453, + -3.2111854553222656, + -4.606469631195068, + -0.37273675203323364, + 5.017423152923584, + 5.4608588218688965, + 19.352506637573242, + -1.0860271453857422, + 16.13364028930664, + 8.224601745605469, + -1.6798858642578125, + 1.9735264778137207, + 2.723505973815918, + 7.066295146942139, + 3.674107789993286, + -3.3889405727386475, + 14.024727821350098, + 11.167510986328125, + -1.8341599702835083, + -1.0200282335281372, + -1.2598223686218262, + -0.6529378294944763, + 8.153664588928223, + 4.783754825592041, + 18.81198501586914, + 5.598753929138184, + -3.532395124435425, + -4.371533393859863, + -2.9367051124572754, + 6.893309116363525, + 1.3952419757843018, + 3.7393786907196045, + 1.7668650150299072, + 3.434063196182251, + 4.041042327880859, + 19.04979133605957, + 14.945502281188965, + 2.1760034561157227, + 11.23580265045166, + 4.729201316833496, + 13.440740585327148, + 6.5333733558654785, + -2.428642749786377, + -3.8284177780151367, + -1.25637948513031, + 19.01990509033203, + 4.050504207611084, + 10.37231159210205, + 6.333662509918213, + 8.26085376739502, + 0.26365381479263306, + -0.7908855080604553, + 6.86776065826416, + 8.06732177734375, + 8.8652982711792, + 1.2226016521453857, + 8.232060432434082, + 0.5213705897331238, + 5.977219581604004, + 5.325591564178467, + 3.8152976036071777, + 6.1850080490112305, + 3.2645487785339355, + 11.23431396484375, + -1.6207003593444824, + 5.4807233810424805, + 8.250093460083008, + -4.346365928649902, + -0.4443540871143341, + 8.2500638961792, + 8.132844924926758, + 0.06219557672739029, + -1.1040263175964355, + 19.418800354003906, + 17.168012619018555, + -1.106479525566101, + -0.08850227296352386, + 5.08074951171875, + 18.56949234008789, + 18.320371627807617, + -1.4364665746688843, + -1.6998034715652466, + 18.649545669555664, + 9.306314468383789, + 19.28203010559082, + 6.133315086364746, + 10.848103523254395, + 9.586997985839844, + -3.1336185932159424, + 2.1478447914123535, + -4.410467624664307, + 17.168922424316406, + 3.5915656089782715, + -2.3382186889648438, + 17.16809844970703, + -3.1225404739379883, + -3.8302512168884277, + 18.434350967407227, + 2.9570155143737793, + -4.108340740203857 + ], + "z": [ + 1.4177736043930054, + 3.5685086250305176, + 1.409437656402588, + -2.9852678775787354, + 7.083601951599121, + -0.6847020387649536, + -2.441432476043701, + -2.2293479442596436, + 1.2630575895309448, + 10.146768569946289, + -2.4585843086242676, + -3.11897873878479, + 1.2666568756103516, + 1.4752161502838135, + 1.5091975927352905, + 7.7980637550354, + -3.056428909301758, + 9.835917472839355, + -3.405787944793701, + -2.9410839080810547, + -2.8661227226257324, + 1.016663670539856, + 1.3860148191452026, + -3.7722082138061523, + 3.259014368057251, + -3.9223268032073975, + -1.6303712129592896, + 9.472508430480957, + 2.112422466278076, + -0.9354557394981384, + 3.004180431365967, + 9.838616371154785, + 10.825183868408203, + -3.3392398357391357, + -3.3676631450653076, + -2.283379316329956, + 1.3363865613937378, + -2.446209669113159, + 8.5270357131958, + 1.7216577529907227, + 1.9780998229980469, + 2.8438827991485596, + 3.087479829788208, + 0.04693915322422981, + 4.899574279785156, + 10.881864547729492, + -1.0147744417190552, + 7.496772289276123, + 8.274809837341309, + 10.108009338378906, + 1.7144241333007812, + -1.2504663467407227, + -4.437587738037109, + 5.679888725280762, + -2.0013604164123535, + -3.981717348098755, + 5.043292045593262, + -2.376406192779541, + 1.7331440448760986, + 1.1964457035064697, + 9.325284004211426, + 2.9916107654571533, + 8.32998275756836, + 2.581134080886841, + 11.016107559204102, + 5.788521766662598, + 8.114748001098633, + -0.7892840504646301, + 11.00765609741211, + 5.583750247955322, + -3.033865451812744, + 1.4001201391220093, + 4.887108325958252, + -1.167651891708374, + 10.336536407470703, + 3.2511184215545654, + 10.109580039978027, + 6.7864837646484375, + 6.484445571899414, + 4.583970546722412, + 4.598883628845215, + 0.18130303919315338, + 1.3827550411224365, + 0.7197452783584595, + 10.874858856201172, + 5.2740983963012695, + -0.6189326047897339, + 5.247952938079834, + 1.33085298538208, + -2.8275909423828125, + 1.8819042444229126, + 5.518457412719727, + 4.707382678985596, + -0.7091772556304932, + 3.9156453609466553, + 1.1510512828826904, + -2.5375096797943115, + -3.0887622833251953, + -2.556938886642456, + -2.4860103130340576, + 3.525174617767334, + -0.9997326135635376, + -0.25042444467544556, + 4.563737869262695, + 0.21988123655319214, + -2.4720237255096436, + 2.6473917961120605, + 1.3859127759933472, + 1.7731854915618896, + 4.0852484703063965, + -4.124099254608154, + -0.41867733001708984, + 9.834892272949219, + -0.9554709792137146, + 5.993447780609131, + 3.08553147315979, + 4.35844612121582, + 8.145562171936035, + 9.828862190246582, + -0.7834453582763672, + 8.286669731140137, + 6.295088291168213, + -2.204766273498535, + -2.219895839691162, + 10.56722640991211, + 2.262876510620117, + 5.241689682006836, + 4.573790550231934, + 4.6208271980285645, + 3.325031280517578, + 6.650082588195801, + 7.291085720062256, + 6.240830421447754, + 5.510115623474121, + 3.5721218585968018, + -3.044801950454712, + 7.682680606842041, + 1.3659559488296509, + 1.9566121101379395, + 0.5504336357116699, + 7.361408233642578, + 0.7413011193275452, + 9.095999717712402, + 0.8872936367988586, + 7.446047306060791, + 9.455489158630371, + 1.9577102661132812, + 8.251739501953125, + -1.5967031717300415, + 4.757504463195801, + 3.5968849658966064, + 3.2808728218078613, + 1.1083872318267822, + 3.271106004714966, + 10.906517028808594, + 3.083745241165161, + 7.302727699279785, + 7.983012676239014, + -0.17172880470752716, + -0.32537850737571716, + -0.27705076336860657, + 9.472542762756348, + 3.5989303588867188, + 2.992967367172241, + 6.016650199890137, + 0.4410635530948639, + 8.51346206665039, + 8.348111152648926, + 6.9538493156433105, + -0.42862239480018616, + 10.36401081085205, + 5.94595193862915, + 7.34079122543335, + 7.536102294921875, + 4.530074119567871, + 6.369518280029297, + 7.762298107147217, + 9.63827133178711, + 4.037099361419678, + -0.42644113302230835, + 2.9270355701446533, + 1.1332643032073975, + 8.393031120300293, + -0.10080910474061966, + 8.978371620178223, + 6.890629291534424, + -1.1461604833602905, + 1.1193658113479614, + 6.216001987457275, + 3.0642688274383545, + -0.7392174601554871, + -0.4026583731174469, + 1.2356318235397339, + -1.3587450981140137, + 1.5121018886566162, + 1.4828565120697021, + 5.91876220703125, + 6.074442386627197, + 2.041517972946167, + 8.016969680786133, + 9.836990356445312, + 1.8373093605041504, + 11.016724586486816, + 5.749871253967285, + 8.969491004943848, + 1.2849568128585815, + 7.232442855834961, + 7.205903053283691, + 2.1471214294433594, + 10.119808197021484, + 3.6665072441101074, + 4.21311092376709, + 10.96550464630127, + 10.873600006103516, + 1.945432186126709, + 7.98313570022583, + 10.892903327941895, + 10.612506866455078, + 0.6066908836364746, + 1.9788193702697754, + 6.356741905212402, + 8.968859672546387, + 1.7373394966125488, + 10.616158485412598, + 6.055818557739258, + 10.143609046936035, + 10.021368980407715, + 7.796103477478027, + 11.066326141357422, + 5.801746368408203, + 1.74177885055542, + 0.5144570469856262, + 10.944040298461914, + 6.447906970977783, + 3.4628584384918213, + 4.792663097381592, + 6.364314556121826, + 0.1247197687625885, + -2.283083200454712, + 8.005939483642578, + -2.440946578979492, + -0.8882617354393005, + 5.16242790222168, + 9.477262496948242, + -2.6902503967285156, + 8.403070449829102, + 4.224328517913818, + 3.597759962081909, + 6.253907203674316, + 4.596164226531982, + 2.0813636779785156, + 2.1991777420043945, + 0.4383654296398163, + 10.1263427734375, + 11.007566452026367, + 5.130825042724609, + 0.5266510248184204, + 11.013590812683105, + 1.3519277572631836, + 7.4287590980529785, + 10.753594398498535, + 2.792851448059082, + 3.4667434692382812, + -2.3937361240386963, + 7.382382869720459, + 0.5364453792572021, + 7.115087509155273, + 3.597989559173584, + 5.683960914611816, + 0.6472503542900085, + 2.778059244155884, + 3.689436912536621, + 4.551624298095703, + -0.7999021410942078, + 9.47193717956543, + -1.5839760303497314, + 4.802641868591309, + 4.999964237213135, + -0.3973662853240967, + 6.365986347198486, + -2.237293004989624, + 7.495091915130615, + 10.968998908996582, + 1.1243572235107422, + 4.679996490478516, + 9.096270561218262, + 2.6339151859283447, + 2.3833208084106445, + 10.57094669342041, + 9.487264633178711, + -1.5424672365188599, + 8.185632705688477, + 5.005161285400391, + 3.2116780281066895, + 10.561934471130371, + 3.0829997062683105, + 9.288578033447266, + 3.2935521602630615, + -3.1863276958465576, + 1.6162971258163452, + 1.455981731414795, + 3.5981016159057617, + 6.7892351150512695, + -2.37351131439209, + -0.25547611713409424, + -2.8799867630004883, + 7.180281639099121, + 8.9627103805542, + 10.023725509643555, + 10.614104270935059, + 2.000675678253174, + -2.280263662338257, + 7.39827823638916, + 5.53359317779541, + 2.295045852661133, + 4.627181053161621, + 10.380684852600098, + 7.050445079803467, + 8.695112228393555, + -3.220405101776123, + 10.874719619750977, + 7.5529913902282715, + 10.875029563903809, + 1.2706769704818726, + 10.81451416015625, + -0.6022406220436096, + 1.3271039724349976, + 6.373929500579834, + -1.5099340677261353, + 10.616965293884277, + -3.163989305496216, + 7.164882659912109, + 3.3733551502227783, + 4.502981662750244, + -0.7010960578918457, + -0.011516972444951534, + -0.2986781895160675, + 4.327503204345703, + 6.3242506980896, + 3.0129475593566895, + -0.08799010515213013, + 5.387620449066162, + 8.246081352233887, + 3.2766785621643066, + 5.579555988311768, + 7.605876922607422, + 7.167038440704346, + -3.2258756160736084, + 6.716490745544434, + 7.317634105682373, + -1.0654946565628052, + 10.571725845336914, + -0.4775194525718689, + 2.0692412853240967, + 4.759147644042969, + 1.5270689725875854, + 9.427855491638184, + 0.25206124782562256, + 9.823604583740234, + -4.25587272644043, + 10.81533432006836, + 8.457674026489258, + 1.3878636360168457, + 6.324974060058594, + 7.434532642364502, + 0.3931970000267029, + 1.3965883255004883, + 7.196897983551025, + -0.6467228531837463, + 3.083073854446411, + 8.265838623046875, + 10.205825805664062, + 2.0296905040740967, + -2.0664680004119873, + 1.407500982284546, + 4.422662258148193, + 2.002337694168091, + -2.1057186126708984, + 9.574884414672852, + -3.946733236312866, + -1.9400602579116821, + -1.9563381671905518, + 6.891944408416748, + 1.4617115259170532, + 8.373838424682617, + 2.7873425483703613, + 8.937978744506836, + 1.368007779121399, + 5.388151168823242, + -0.474201500415802, + 6.627046585083008, + 4.084752082824707, + 5.939820289611816, + 7.294437408447266, + 7.136241436004639, + 1.4644197225570679, + -2.2142436504364014, + 1.4790579080581665, + 0.65131676197052, + 6.773548126220703, + 7.370126724243164, + 6.840259075164795, + 5.326922416687012, + 6.511779308319092, + 7.483944892883301, + 4.980292320251465, + -0.2492542862892151, + 6.869568824768066, + 7.751910209655762, + -1.0449966192245483, + 10.337574005126953, + 11.016663551330566, + 2.220552444458008, + -0.27446964383125305, + 4.398221015930176, + 7.48680305480957, + -0.7997992634773254, + 8.546785354614258, + 8.266009330749512, + 11.014884948730469, + -3.5099613666534424, + 1.6751708984375, + 10.115920066833496, + 10.590869903564453, + 8.251962661743164, + -2.559415817260742, + 10.75151252746582, + -2.6736578941345215, + 9.47006893157959, + -2.7377769947052, + 6.346122741699219, + 11.002530097961426, + 11.051237106323242, + 6.7978997230529785, + 1.1287025213241577, + 3.1907618045806885, + 8.303216934204102, + 2.6445975303649902, + 5.346555233001709, + 1.5319219827651978, + -0.9179970026016235, + 8.96486759185791, + 3.626824378967285, + -2.571998357772827, + 10.042567253112793, + 5.285177707672119, + 6.008552551269531, + 10.568145751953125, + 10.357549667358398, + 5.9587531089782715, + 2.2894527912139893, + 1.4141461849212646, + 10.047780990600586, + -0.038237761706113815, + 8.970501899719238, + 10.880523681640625, + 5.581862926483154, + 10.964479446411133, + 9.475570678710938, + 5.642027378082275, + 6.017795562744141, + 8.795964241027832, + 7.145466327667236, + 8.268378257751465, + 6.292470932006836, + 1.317997694015503, + 9.659209251403809, + 12.657670021057129, + 2.0253400802612305, + 7.344221115112305, + 4.845076084136963, + 0.5502208471298218, + -4.155119895935059, + 2.828845739364624, + 10.761252403259277, + -1.6185485124588013, + 2.409069538116455, + 7.697107315063477, + 8.445408821105957, + 1.3783663511276245, + 2.0059807300567627, + 7.356954574584961, + 6.997552871704102, + -2.9658119678497314, + 6.645395278930664, + 6.3547210693359375, + 6.945919513702393, + -1.627782940864563, + 9.679655075073242, + 6.671004295349121, + 7.258305549621582, + 4.964713096618652, + 7.024662017822266, + 7.405595302581787, + 10.396926879882812, + 5.825431823730469, + 10.942770004272461, + -3.6519577503204346, + 10.887704849243164, + -1.8735628128051758, + 5.321141719818115, + 6.542881488800049, + 8.468877792358398, + 7.364691257476807, + 6.976491928100586, + 10.95433521270752, + -2.6856424808502197, + 1.0056231021881104, + 1.762937068939209, + 1.0085933208465576, + 9.470072746276855, + 0.6760926842689514, + 10.345675468444824, + 2.316739559173584, + 2.912243127822876, + 9.200601577758789, + 1.141264796257019, + -0.2678775191307068, + 5.557638168334961, + -2.6811320781707764, + 6.337548732757568, + 10.984707832336426, + 3.725064516067505, + 8.290990829467773, + 12.669785499572754, + 6.2387800216674805, + 8.397769927978516, + 12.669829368591309, + 2.8718724250793457, + 9.038887023925781, + -1.620595097541809, + 6.115710258483887, + 8.77137565612793, + 8.529285430908203, + 8.828253746032715, + -0.41212397813796997, + 7.424262523651123, + 7.960896015167236, + 8.133879661560059, + 2.1260650157928467, + 7.421261310577393, + 4.589494705200195, + 6.94594144821167, + -1.9682062864303589, + 10.342230796813965, + 10.607640266418457, + 2.300664186477661, + 3.3788607120513916, + 5.692849159240723, + 8.770729064941406, + -3.9737117290496826, + 2.324803352355957, + 8.77044677734375, + 6.983893871307373, + 6.660764694213867, + 7.24354887008667, + 4.926337242126465, + 3.103992462158203 + ], + "type": "scatter3d" + }, + { + "hovertemplate": "Dominant_Topic=Topic 3
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 3", + "name": "Dominant_Topic=Topic 3", + "scene": "scene", + "y": [ + 6.008767604827881, + 11.917278289794922, + 6.450388431549072, + 6.926000118255615, + 6.289341926574707, + 8.560750961303711, + 10.073214530944824, + 11.261116027832031, + 10.920854568481445, + 10.4088134765625, + 11.53973388671875, + -6.3690505027771, + 11.298784255981445, + 9.26341724395752, + 8.02541732788086, + -5.3535847663879395, + -6.4288330078125, + 10.209124565124512, + 5.314403533935547, + 8.75598430633545, + 7.868958473205566, + 9.39208984375, + 9.77348518371582, + 5.141706466674805, + 9.624744415283203, + 9.931181907653809, + 11.842582702636719, + 10.164289474487305, + 9.350129127502441, + 9.05660343170166, + 11.568628311157227, + -6.55482292175293, + -6.409642219543457, + 11.4131498336792, + 10.665776252746582, + 8.017780303955078, + -6.653383255004883, + 10.74891471862793, + 11.033449172973633, + 10.53691291809082, + 8.340717315673828, + 11.415642738342285, + 10.225553512573242, + 9.714183807373047, + 8.54741096496582, + -5.5740647315979, + 11.629408836364746, + 10.92938232421875, + 8.315319061279297, + 10.832318305969238, + 10.280227661132812, + 10.63483715057373, + 10.513654708862305, + 11.440350532531738, + -6.223934650421143, + 8.42694091796875, + 11.91189193725586, + 10.158048629760742, + 8.790985107421875, + -6.525151252746582, + 7.671194076538086, + 8.595170974731445, + 11.551204681396484, + 11.598661422729492, + 8.767753601074219, + 8.917595863342285, + 11.651330947875977, + 11.520066261291504, + 10.12695026397705, + 9.875666618347168, + 9.277520179748535, + 10.5537691116333, + 9.105364799499512, + 7.827974796295166, + 8.645140647888184, + 7.139874458312988, + 11.163177490234375, + 9.161416053771973, + 9.299068450927734, + 10.268099784851074, + 6.758927822113037, + 7.338631629943848, + 9.732832908630371, + 10.065598487854004, + 11.160318374633789, + 10.819921493530273, + 6.774186611175537, + 11.869461059570312, + 10.744978904724121, + 5.094717979431152, + 9.341403007507324, + 8.158247947692871, + 7.888888835906982, + 8.378146171569824, + -6.754744529724121, + -6.800960540771484, + 10.109713554382324, + 8.825704574584961, + 10.723709106445312, + 12.086037635803223, + 8.347618103027344, + 9.65743350982666, + -6.128290176391602, + 5.181214809417725, + 10.972081184387207, + 8.703518867492676, + 10.07766056060791, + 9.243167877197266, + 7.921475887298584, + 11.807514190673828, + 9.203633308410645, + -6.128615856170654, + 11.336105346679688, + 10.162121772766113, + 8.308917045593262, + 11.15987777709961, + 10.158307075500488, + 7.733555793762207, + 10.202940940856934, + 11.449048042297363, + 11.960409164428711, + 9.087095260620117, + -6.2883687019348145, + 11.646134376525879, + 10.519686698913574, + 8.241053581237793, + 11.595703125, + 10.11941909790039, + 9.731989860534668, + 7.2806549072265625, + 6.055694580078125, + 8.147161483764648, + 11.805498123168945, + 7.840851306915283, + 9.010945320129395, + 11.056442260742188, + 9.24459457397461, + 12.016393661499023, + 8.452997207641602 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#ab63fa", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + -4.587766647338867, + -9.396677017211914, + -8.108192443847656, + -7.96483850479126, + -8.92051887512207, + -8.146102905273438, + -2.4850261211395264, + -8.953971862792969, + -6.163597583770752, + -8.026777267456055, + -10.036551475524902, + 5.65316104888916, + -7.089688777923584, + -7.773583889007568, + -8.137612342834473, + 7.269197940826416, + 5.648162364959717, + -1.8204030990600586, + -3.392869234085083, + -3.334242343902588, + -6.2734761238098145, + -7.672241687774658, + -4.6007585525512695, + -6.836556911468506, + -1.994957447052002, + -4.389632225036621, + -10.06650161743164, + -3.244786024093628, + -8.606729507446289, + -7.297788619995117, + -9.983890533447266, + 5.5989484786987305, + 6.012876033782959, + -9.318669319152832, + -5.223183631896973, + -1.1838418245315552, + 5.572573661804199, + -5.3690104484558105, + -9.712583541870117, + -5.013570785522461, + -6.707099437713623, + -9.399011611938477, + -3.675349712371826, + -4.589323043823242, + -3.197967767715454, + 7.078281402587891, + -9.480172157287598, + -6.234033584594727, + -5.000112056732178, + -8.318731307983398, + -4.21071195602417, + -5.029570579528809, + -4.8565497398376465, + -8.366124153137207, + 5.619945526123047, + -8.245251655578613, + -9.84970760345459, + -7.250147342681885, + -7.761618614196777, + 5.626148700714111, + -6.4991559982299805, + -3.3866500854492188, + -9.481075286865234, + -7.565962314605713, + -7.0567803382873535, + -7.31330680847168, + -9.669180870056152, + -9.626030921936035, + -2.1421010494232178, + -4.900909900665283, + -7.645026683807373, + -4.991934299468994, + -7.423114776611328, + -6.033771991729736, + -7.012484550476074, + -1.1238564252853394, + -8.801837921142578, + -3.6375176906585693, + -3.6255602836608887, + -8.201844215393066, + -3.8143842220306396, + -1.9822322130203247, + -6.249452114105225, + -7.868195533752441, + -8.792265892028809, + -8.30465316772461, + -7.934676647186279, + -9.841388702392578, + -9.523598670959473, + -6.911177158355713, + -7.714823246002197, + -1.141294002532959, + -6.285341262817383, + -8.224363327026367, + 5.665600776672363, + 5.556366443634033, + -4.406745433807373, + -7.24278450012207, + -5.280751705169678, + -9.816762924194336, + -6.741730690002441, + -3.7904207706451416, + 6.0386576652526855, + -6.831153869628906, + -6.364618301391602, + -7.118622303009033, + -3.2217447757720947, + -7.607378005981445, + -8.069018363952637, + -9.341931343078613, + -7.609137058258057, + 3.732539176940918, + -9.078180313110352, + -7.254886150360107, + -5.3130645751953125, + -8.793814659118652, + -7.248284816741943, + -6.231448650360107, + -3.9769794940948486, + -8.336015701293945, + -10.093538284301758, + -7.4956207275390625, + 5.60312557220459, + -10.038368225097656, + -7.838123321533203, + -6.589437007904053, + -7.504143238067627, + -8.10136604309082, + -6.246973037719727, + -2.354736566543579, + -4.202754020690918, + -1.2691309452056885, + -9.341570854187012, + -8.114169120788574, + -7.493973731994629, + -6.198458194732666, + -7.651123523712158, + -9.520598411560059, + -5.06498908996582 + ], + "z": [ + 2.6942977905273438, + 1.0377497673034668, + 0.8172392845153809, + 0.5559206008911133, + 1.115695834159851, + -0.03952707350254059, + 1.2344212532043457, + 0.6817474961280823, + 0.0030658647883683443, + -1.171251893043518, + 1.2679829597473145, + 2.78867506980896, + -0.2468714863061905, + -1.262664794921875, + 0.2165345400571823, + 1.3677301406860352, + 2.6699016094207764, + 1.3336801528930664, + 1.631797194480896, + 0.5425270199775696, + -5.0460710525512695, + -2.696237325668335, + -2.045781373977661, + -1.304282307624817, + 1.1596907377243042, + -0.9522325992584229, + 1.4599231481552124, + 1.1704493761062622, + 0.4374038875102997, + -3.52266001701355, + 0.9995434880256653, + 2.5136704444885254, + 1.939632534980774, + 0.3072001338005066, + 0.8494616150856018, + -1.1421698331832886, + 2.3652141094207764, + 0.9807437658309937, + 1.1499054431915283, + 0.6104476451873779, + -4.523981094360352, + 1.212567687034607, + 1.1127501726150513, + -2.0869781970977783, + 0.4921557903289795, + 1.3751977682113647, + 1.4784163236618042, + 1.0375558137893677, + -3.9460127353668213, + 0.16787202656269073, + 0.9914725422859192, + 0.961077868938446, + 0.8417032361030579, + 1.1996684074401855, + 3.1544108390808105, + 0.19368652999401093, + 1.5430630445480347, + -0.5343848466873169, + -1.0433790683746338, + 2.509176254272461, + -3.6389777660369873, + 0.46361106634140015, + 1.4489548206329346, + -0.289328932762146, + -3.969249725341797, + -3.800766944885254, + 0.607326865196228, + 1.4965989589691162, + 1.2526214122772217, + -1.6801944971084595, + -3.1430320739746094, + 0.8234795331954956, + -3.2551095485687256, + -5.041479110717773, + -4.08875036239624, + -2.481555938720703, + 0.5711416006088257, + 0.6292800307273865, + 1.8602253198623657, + -1.3533334732055664, + 2.6225852966308594, + -2.9181342124938965, + -0.8591957688331604, + -1.28269624710083, + 0.5657196640968323, + 0.15602245926856995, + 0.6198409199714661, + 0.8960171341896057, + 1.0755712985992432, + -1.3143848180770874, + -3.0985491275787354, + -0.8954681158065796, + -5.0173821449279785, + 0.18392452597618103, + 1.9487855434417725, + 1.6409913301467896, + -0.4043935239315033, + -4.028177738189697, + 0.9775936603546143, + 1.157893180847168, + -4.5960893630981445, + 1.6006791591644287, + 2.462540626525879, + -1.3881194591522217, + 1.091137170791626, + -4.185579299926758, + 1.1631629467010498, + -3.3102705478668213, + 0.19569508731365204, + 0.9687861204147339, + -3.387805938720703, + -3.0501532554626465, + 0.7851496934890747, + -0.5322110056877136, + -4.045925617218018, + 0.5665538311004639, + -0.5338267087936401, + -5.260075569152832, + 1.0379866361618042, + 1.2308334112167358, + 1.4024760723114014, + -3.572606325149536, + 3.076082229614258, + 1.0346672534942627, + -0.20047441124916077, + -4.615255832672119, + -0.31848812103271484, + -1.5747030973434448, + -0.8610705733299255, + -3.272325038909912, + 2.7500228881835938, + -0.9696059823036194, + 0.9661428928375244, + 0.2733951807022095, + -3.3137388229370117, + -0.34486961364746094, + -3.3338310718536377, + 1.2987961769104004, + -3.804863452911377 + ], + "type": "scatter3d" + }, + { + "hovertemplate": "Dominant_Topic=Topic 4
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 4", + "name": "Dominant_Topic=Topic 4", + "scene": "scene", + "y": [ + -6.071606636047363, + 1.401357889175415, + 5.898947715759277, + 5.849190711975098, + -2.5958728790283203, + -7.828892707824707, + 1.0187311172485352, + 4.972972869873047, + 0.7781368494033813, + -4.392882823944092, + 0.6708770990371704, + -5.4186248779296875, + 5.022832870483398, + -0.1653873324394226, + 2.124833583831787, + 1.5491514205932617, + -6.8587327003479, + -5.193793296813965, + 2.1446053981781006, + -2.7164618968963623, + -7.369263172149658, + -5.584724426269531, + -5.723509311676025, + -5.757503509521484, + -2.1086161136627197, + -0.8570528030395508, + -2.9060685634613037, + 0.970962405204773, + -7.821597576141357, + -7.5585832595825195, + 3.0470707416534424, + -5.028545379638672, + -7.507384300231934, + -3.8960013389587402, + -6.834227561950684, + -3.1449100971221924, + 0.3415597677230835, + -5.195375919342041, + -3.2205183506011963, + -5.864113807678223, + -2.633901357650757, + -2.278933048248291, + -6.931227207183838, + 2.1358940601348877, + -6.070683002471924, + 2.186572790145874, + -5.030484676361084, + 2.197345495223999, + -7.1646599769592285, + -0.8545822501182556, + 2.355489730834961, + 3.124384880065918, + -2.844658136367798, + 5.092371940612793, + 0.5056561231613159, + -1.7947883605957031, + -6.21515417098999, + 0.9713303446769714, + 0.9340984225273132, + -5.720623970031738, + -4.5821309089660645, + -5.590975761413574, + 2.8778939247131348, + -1.18522047996521, + -7.3541483879089355, + -4.778873443603516, + -5.654862403869629, + -5.839632511138916, + -4.764888286590576, + -0.14246729016304016, + -5.314829349517822, + 0.8919858932495117, + 2.5077807903289795, + 5.747104644775391, + -8.023880004882812, + -5.61793327331543, + 4.146553993225098, + -4.378360748291016, + -7.669914245605469, + -3.4955902099609375, + -5.903852939605713, + 2.831315040588379, + 0.863471508026123, + 5.442622184753418, + -2.730618476867676, + -4.3569207191467285, + -0.576200544834137, + -3.992827892303467, + -7.727400302886963, + 0.36453163623809814, + 1.1452592611312866, + -2.335695266723633, + 1.0915911197662354, + 0.5890882015228271, + -5.58621072769165, + -5.790203094482422, + -5.770488262176514, + -2.344247341156006, + -4.55132532119751, + -0.2529362142086029, + 1.2772480249404907, + 3.92608904838562, + -4.26770544052124, + -2.145080327987671, + -8.114397048950195, + -6.069690227508545, + -7.238351345062256, + -0.0005485013825818896, + -7.010998725891113, + 5.098325729370117, + 1.1605979204177856, + -4.836550235748291, + -4.2177019119262695, + -2.533156633377075, + 0.8338998556137085, + -5.836912155151367, + 1.1040879487991333, + 1.2358043193817139, + -2.8706064224243164, + -5.786635398864746, + 2.232710123062134, + -2.175468683242798, + -5.691901683807373, + 1.611864686012268, + 0.709669828414917, + 1.9608203172683716, + 4.9541730880737305, + -2.7813611030578613, + 2.8770055770874023, + 2.4640302658081055, + -6.548416614532471, + 2.564161777496338, + -5.197566032409668, + -3.850414514541626, + 2.131685733795166, + -7.394726276397705, + -4.198235988616943, + 1.031998872756958, + 2.0653679370880127, + -3.1939945220947266, + 1.6972153186798096, + -7.848442077636719, + -6.290923595428467, + 0.973434329032898, + 2.55318546295166, + -3.430600881576538, + -6.088851451873779, + -6.548141956329346, + -7.964238166809082, + 0.7897396683692932, + -8.325608253479004, + 1.0719571113586426, + -0.7324086427688599, + -5.196066379547119, + 4.114058971405029, + 1.0797381401062012, + 1.0163174867630005, + -6.682871341705322, + -3.440096855163574, + -3.0578982830047607, + 5.212983131408691, + 3.95261287689209, + 2.6937010288238525, + -4.635089874267578, + -7.05810546875, + 2.3527603149414062, + -0.25726959109306335, + 2.187889575958252, + -4.100977420806885, + -3.873718023300171, + -5.84706974029541, + -0.9884918928146362, + -7.341245174407959, + -7.8181986808776855, + -4.833110332489014, + -1.0838704109191895, + -5.033321380615234, + 2.364699125289917, + 2.418470859527588, + -6.6120405197143555, + 1.0756467580795288, + 2.09853196144104, + -7.168651580810547, + -8.040593147277832, + -3.1947500705718994, + 0.8472082614898682, + 0.7270042896270752, + 0.5406637787818909, + -4.911299705505371, + 2.1304891109466553, + 5.728253364562988, + 1.741153597831726, + -3.8667995929718018, + -5.984241962432861, + -5.847525596618652, + 2.763313055038452, + -6.66654634475708, + 0.9143350124359131, + -5.187180519104004, + 0.9894624352455139, + -5.759769439697266, + -2.2392959594726562, + 5.430511951446533, + -5.680849552154541, + -8.130134582519531, + -5.756889343261719, + -3.4368174076080322, + -5.133642196655273, + -5.7641825675964355, + -3.438478469848633, + -6.140925884246826, + -5.783359527587891, + -8.32055377960205, + -4.381443977355957, + -4.834843635559082, + 2.7423064708709717, + -2.743601083755493, + -6.0706353187561035, + -7.123063087463379, + -4.855417251586914, + 3.8591108322143555, + -7.005795955657959, + -8.229113578796387 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#FFA15A", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + -1.3701810836791992, + -7.617319107055664, + -4.357903957366943, + -7.739718914031982, + -4.504122734069824, + -13.650049209594727, + -7.367645740509033, + -7.600283145904541, + -8.189477920532227, + -9.03403377532959, + -8.16067886352539, + -10.31457233428955, + -6.58879280090332, + -8.790830612182617, + -6.648097991943359, + -7.400576114654541, + -12.648568153381348, + -8.871949195861816, + -6.597644329071045, + -9.872652053833008, + -13.032196998596191, + -10.746192932128906, + -11.053606986999512, + -2.6013245582580566, + -9.8052978515625, + -7.275606155395508, + -5.649023532867432, + -8.048131942749023, + -13.282407760620117, + -13.450089454650879, + -4.98770809173584, + -9.521116256713867, + -13.67598819732666, + -10.855460166931152, + -9.513588905334473, + -8.722573280334473, + -8.44426155090332, + -9.773736000061035, + -10.491998672485352, + -11.320596694946289, + -4.739925861358643, + -9.895997047424316, + -9.717628479003906, + -4.248871803283691, + -11.68474292755127, + -4.538839340209961, + -9.525321960449219, + -6.4433135986328125, + -12.933785438537598, + -3.2794463634490967, + -4.709289073944092, + -4.574557781219482, + -5.472368240356445, + -7.628293514251709, + -8.265690803527832, + -4.102863311767578, + -11.873306274414062, + -8.057440757751465, + -7.765010833740234, + -2.5587844848632812, + -1.8540921211242676, + -10.762451171875, + -4.69534969329834, + -3.373535633087158, + -13.553145408630371, + -9.278267860412598, + -10.936814308166504, + -11.325478553771973, + -9.268336296081543, + -8.821651458740234, + -10.037482261657715, + -8.223034858703613, + -4.6294145584106445, + -7.77821159362793, + -14.035411834716797, + -9.24109935760498, + -5.067386627197266, + -9.032715797424316, + -13.11492919921875, + -10.569192886352539, + -11.445009231567383, + -5.335042476654053, + -7.92094087600708, + -7.637786388397217, + -5.150529861450195, + -1.7893428802490234, + -8.392709732055664, + -10.918272972106934, + -13.953357696533203, + -8.306573867797852, + -7.980172157287598, + -9.921188354492188, + -7.870840072631836, + -8.445858001708984, + -10.757532119750977, + -11.20375919342041, + -9.393991470336914, + -9.927067756652832, + -11.162343978881836, + -8.885481834411621, + -7.820388317108154, + -5.595799922943115, + -1.8016326427459717, + -9.67346477508545, + -13.374540328979492, + -11.685783386230469, + -13.251459121704102, + -8.776627540588379, + -12.821443557739258, + -6.8672380447387695, + -7.557442665100098, + -11.437626838684082, + -7.261577606201172, + -4.559615612030029, + -7.96628999710083, + -1.9350565671920776, + -7.159169673919678, + -6.55112886428833, + -9.902170181274414, + -11.194003105163574, + -6.4100775718688965, + -9.826356887817383, + -2.857811212539673, + -5.0618577003479, + -8.131704330444336, + -7.608196258544922, + -7.517548084259033, + -9.734293937683105, + -5.256678581237793, + -5.983100414276123, + -12.26356315612793, + -5.746590614318848, + -9.782747268676758, + -8.798480987548828, + -4.742132186889648, + -13.20771598815918, + -7.2577924728393555, + -7.527723789215088, + -6.646272659301758, + -10.463540077209473, + -4.773765563964844, + -13.683629989624023, + -11.954787254333496, + -7.241000175476074, + -5.802192211151123, + -8.659486770629883, + -12.925819396972656, + -12.26131534576416, + -13.807026863098145, + -8.319202423095703, + -13.728191375732422, + -4.873146057128906, + -7.4036149978637695, + -9.777303695678711, + -4.745284557342529, + -8.062438011169434, + -7.265244483947754, + -9.47213077545166, + -8.660848617553711, + -5.862987995147705, + -7.5369439125061035, + -7.643502712249756, + -5.298769950866699, + -7.992568016052246, + -12.857024192810059, + -6.102329730987549, + -8.856914520263672, + -3.698996067047119, + -7.326562881469727, + -8.806447982788086, + -11.327489852905273, + -8.027017593383789, + -13.155352592468262, + -14.041378021240234, + 0.21553771197795868, + -3.3148953914642334, + -9.525369644165039, + -4.584224700927734, + -4.643523693084717, + -12.332653999328613, + -7.458972454071045, + -6.631651401519775, + -12.937150001525879, + -13.427024841308594, + -10.472277641296387, + -7.938898086547852, + -8.077173233032227, + -8.242087364196777, + -11.299423217773438, + -7.737955570220947, + -4.75901985168457, + -4.899421691894531, + -8.802800178527832, + -11.565351486206055, + -11.327906608581543, + -4.8880228996276855, + -12.399471282958984, + -7.793229579925537, + -9.159722328186035, + -7.740940093994141, + -2.6524999141693115, + -9.862488746643066, + -7.635049343109131, + -9.252899169921875, + -13.999748229980469, + -2.3449153900146484, + -8.660867691040039, + -8.83621597290039, + -2.4829912185668945, + -8.663690567016602, + -1.1976481676101685, + -2.530172824859619, + -13.756771087646484, + -7.497959613800049, + -11.432727813720703, + -3.2889456748962402, + -5.237927436828613, + -11.684706687927246, + -12.905235290527344, + 0.3958384394645691, + -5.199071884155273, + -9.99421215057373, + -13.594295501708984 + ], + "z": [ + -0.4777602255344391, + 5.707637786865234, + 2.9630417823791504, + 0.9007206559181213, + 5.71491813659668, + 10.426092147827148, + -0.6048240661621094, + 1.2598931789398193, + 5.678791046142578, + 5.3604278564453125, + 1.220111608505249, + 6.474859714508057, + 2.0312650203704834, + 5.9835638999938965, + 5.785152435302734, + 5.708835124969482, + 8.945245742797852, + 3.7479515075683594, + 5.77567720413208, + 4.013669013977051, + 9.680598258972168, + 6.874441623687744, + 7.205873012542725, + -0.005397099070250988, + 6.7665605545043945, + 5.503626823425293, + 5.687474727630615, + 5.6872406005859375, + 9.553071022033691, + 10.165194511413574, + 6.089369773864746, + 5.866951942443848, + 9.62354850769043, + 7.764584541320801, + 6.984760284423828, + 3.976818799972534, + 5.731404781341553, + 6.0489301681518555, + 4.195966720581055, + 7.521050930023193, + 5.699735164642334, + 6.851812839508057, + 7.1714372634887695, + 1.9774293899536133, + 7.919101715087891, + 2.4422340393066406, + 5.871624946594238, + 5.738735198974609, + 9.239606857299805, + 5.271602630615234, + 3.8560452461242676, + 5.785273551940918, + 5.687955379486084, + 0.8800841569900513, + 1.3015297651290894, + 5.521292209625244, + 8.114335060119629, + 5.585608959197998, + 0.6657354831695557, + -0.009351535700261593, + 0.2717103362083435, + 6.892686367034912, + 5.427504062652588, + 5.361150741577148, + 9.803807258605957, + 5.659391403198242, + 7.069247245788574, + 7.53447151184082, + 5.65208625793457, + 6.01632833480835, + 6.2403974533081055, + 5.817348003387451, + 4.335282325744629, + 1.0429800748825073, + 9.94526195526123, + 4.5210065841674805, + 5.125478744506836, + 5.356189250946045, + 9.81908130645752, + 7.500581741333008, + 7.685651779174805, + 5.933167934417725, + 3.182175636291504, + 1.1615869998931885, + 5.684886932373047, + 0.28893935680389404, + 4.616180419921875, + 7.8133015632629395, + 10.240072250366211, + 5.1662702560424805, + 5.76289176940918, + 6.874633312225342, + 5.59456729888916, + 5.859158039093018, + 6.885420799255371, + 7.371055603027344, + 4.7315449714660645, + 6.881059169769287, + 7.9088006019592285, + 6.060513019561768, + 5.750667572021484, + 4.967202186584473, + 0.4053571820259094, + 6.4743475914001465, + 9.86960506439209, + 7.917948246002197, + 9.646886825561523, + 5.998210906982422, + 9.151484489440918, + 1.8124562501907349, + -0.12483403086662292, + 5.374857425689697, + 5.958864688873291, + 5.6324896812438965, + 1.8441133499145508, + -0.2343401163816452, + -0.7852137088775635, + 0.1406649947166443, + 4.276899337768555, + 7.358572959899902, + 5.755969524383545, + 6.774377822875977, + 0.018664119765162468, + 1.076626181602478, + 5.555749893188477, + 0.05071202293038368, + 1.3783783912658691, + 4.380901336669922, + 5.963805675506592, + 5.773224830627441, + 8.533934593200684, + 5.754404067993164, + 6.0534186363220215, + 4.985436916351318, + 5.992695331573486, + 9.30456829071045, + 5.9430460929870605, + -0.13615289330482483, + 5.730916500091553, + 4.190243244171143, + 5.897830963134766, + 9.592571258544922, + 8.200239181518555, + -1.089797854423523, + 5.7792582511901855, + 4.680164813995361, + 8.323741912841797, + 8.53315544128418, + 10.419716835021973, + 5.844794273376465, + 10.077014923095703, + 5.833649158477783, + 5.508872985839844, + 6.050766944885254, + 2.4254064559936523, + 1.1924941539764404, + -0.8530970811843872, + 6.866708755493164, + 4.689970016479492, + 5.708244323730469, + 1.273470163345337, + 1.016109824180603, + 5.700217247009277, + 6.103358745574951, + 9.171135902404785, + 5.701508045196533, + 6.033415794372559, + 1.6532340049743652, + 5.826361179351807, + 5.001322269439697, + 7.528404712677002, + 5.592254161834717, + 9.278629302978516, + 10.16409969329834, + -2.506364107131958, + 5.335336685180664, + 5.868634223937988, + 3.6895298957824707, + 4.036494731903076, + 8.611655235290527, + -0.21284645795822144, + 5.752954959869385, + 9.243268013000488, + 10.324225425720215, + 4.188192844390869, + 2.5880472660064697, + 5.491945743560791, + 1.283861517906189, + 5.485549449920654, + 0.4156278669834137, + 2.76751446723938, + 1.1276203393936157, + 4.996283054351807, + 7.801004409790039, + 7.529197692871094, + 5.34863805770874, + 8.67762565612793, + 0.4312538504600525, + 4.725111961364746, + 0.398896187543869, + 0.009320403449237347, + 6.811234951019287, + 1.1674522161483765, + 4.479031085968018, + 9.952948570251465, + -0.08224864304065704, + 4.686147689819336, + 3.6794533729553223, + -0.04250698164105415, + 4.687036037445068, + -0.552621066570282, + -0.031994763761758804, + 10.069182395935059, + 6.025842666625977, + 5.371954917907715, + 5.313871383666992, + 5.679689884185791, + 7.919083595275879, + 9.222183227539062, + -2.6065831184387207, + 5.229496002197266, + 7.392706871032715, + 10.346153259277344 + ], + "type": "scatter3d" + }, + { + "hovertemplate": "Dominant_Topic=Topic 5
0=%{x}
1=%{y}
2=%{z}", + "showlegend": true, + "legendgroup": "Dominant_Topic=Topic 5", + "name": "Dominant_Topic=Topic 5", + "scene": "scene", + "y": [ + -3.5089550018310547, + 0.5484523177146912, + 6.543319225311279, + 4.946754455566406, + -0.14865218102931976, + 4.762963771820068, + 0.791956901550293, + -1.2287887334823608, + 1.845716953277588, + 0.4479374587535858, + 2.439197063446045, + 1.0972058773040771, + -1.2432416677474976, + 4.758370876312256, + 0.4487791061401367, + 2.4404141902923584, + 1.6130324602127075, + -5.958160400390625, + 2.8911778926849365, + -1.2407411336898804, + -0.5806607604026794, + 1.1296502351760864, + 3.918715238571167, + 1.4379948377609253, + 6.689451217651367, + -0.16903965175151825, + -4.28769063949585, + -1.3357739448547363, + 0.22917622327804565, + 3.6216928958892822, + 4.589448928833008, + -4.476036071777344, + 1.8276569843292236, + 6.077268123626709, + 0.8955190181732178, + 5.036567687988281, + 4.854153633117676, + 8.681123733520508, + 0.1958421766757965, + 1.1383111476898193, + 5.690540313720703, + 0.5512468814849854, + -1.3373188972473145, + 4.1530327796936035, + 0.6548238396644592, + -0.16578377783298492, + -0.4155545234680176, + -0.5793622136116028, + -0.15042884647846222, + -5.898283004760742, + 0.5745519399642944, + -2.9072818756103516, + 2.524563789367676, + -5.661764144897461, + 2.476257562637329, + -0.1884152591228485, + 2.655643939971924, + -1.226538896560669, + 2.577455997467041, + 2.5020484924316406, + -1.001272201538086, + 6.251216411590576, + 2.181100368499756, + 2.317763328552246, + 2.123387575149536, + 2.41469144821167, + 6.642744064331055, + 1.3368394374847412, + 1.221848726272583, + 7.307880878448486, + 7.227151393890381, + 0.5726503729820251, + 2.461364984512329, + -0.9934538006782532, + 2.7756214141845703, + -3.393895387649536, + -1.2309057712554932, + 2.0512821674346924, + 0.37422022223472595, + 2.726531744003296, + 0.9705755114555359, + -0.13740092515945435, + 1.2203384637832642, + 2.5456743240356445, + 2.4208524227142334, + 0.9311517477035522, + 1.083099126815796, + -0.5689033269882202, + 2.4749155044555664, + 4.889718532562256, + 1.0089085102081299, + 2.242351531982422, + -0.20473729074001312, + 6.5673089027404785, + -4.012845516204834, + 7.513089656829834, + 4.459949016571045, + -1.2286041975021362, + 2.4874107837677, + 1.1254328489303589, + -0.14778095483779907, + 0.8015694618225098, + -0.5812502503395081, + 1.1006481647491455, + -0.22679255902767181, + 0.5382842421531677, + -3.4439847469329834, + -5.764045715332031, + 3.9370810985565186, + 1.1148110628128052, + 6.261825084686279, + 2.0367143154144287, + -0.13768887519836426, + -4.997338771820068, + 1.9062913656234741, + -4.316781044006348, + -5.764593601226807, + 2.609454870223999, + 1.9071377515792847, + 7.520583629608154, + 4.815013885498047, + -1.4030057191848755, + 1.9067577123641968, + -3.6350009441375732, + -1.337715744972229, + 0.05254843086004257, + -0.20669983327388763, + 2.2950634956359863, + 0.9726200103759766, + 1.3148659467697144, + -0.16272327303886414, + -2.2079131603240967, + 0.995664119720459, + 5.30906343460083, + 2.708911180496216, + 2.489985227584839, + 2.127983570098877, + -2.2045769691467285, + -5.001999855041504, + 4.561254024505615, + -4.85983943939209, + -0.15628136694431305, + 4.844468593597412, + -1.3369375467300415, + 1.380842924118042, + -0.959533154964447, + 2.3837969303131104, + 1.9718401432037354, + -2.7608189582824707, + -0.35901299118995667, + 0.8915303349494934, + 1.605557918548584, + 0.6511135697364807, + 0.21529416739940643, + -0.43704602122306824, + 1.1690372228622437, + -0.20214134454727173, + 4.859948635101318, + 2.5019688606262207, + 6.37747049331665, + 3.444370746612549, + -0.5817887783050537, + 5.644819259643555, + -0.2873607277870178, + 2.0869030952453613, + 2.067676305770874, + -5.633361339569092, + 1.6906006336212158, + 0.8239738941192627, + 6.706966400146484, + -0.9893884658813477, + 2.4457595348358154, + 4.765473365783691, + -2.7094061374664307, + -3.3314144611358643, + 4.825225353240967, + 1.1141600608825684, + 3.969707489013672, + 1.9070771932601929, + 4.972842693328857, + 0.06703075021505356, + 5.461350917816162, + -4.8649983406066895, + 1.2248291969299316, + -0.3806636333465576, + 4.944002628326416, + 4.657079219818115, + 1.521665096282959, + -1.1798460483551025, + 1.1016802787780762, + -0.40731921792030334, + 3.76914119720459, + 2.833847999572754, + -0.9896969795227051, + 2.4748477935791016, + 1.6214563846588135, + 3.7650744915008545, + 5.849666595458984, + 5.150557994842529, + -0.9787309169769287, + 3.7005419731140137, + 7.437183380126953, + 2.0441529750823975, + 0.916871964931488, + 1.0083529949188232, + 4.855112075805664, + 2.064347505569458, + -2.742048501968384, + -2.870241165161133, + 1.609074354171753, + -0.5693875551223755, + 2.2032997608184814, + -4.359460830688477, + 4.315999984741211, + 4.714355945587158, + -0.5765815377235413, + -5.2880096435546875, + 0.7039323449134827, + 3.284701108932495, + -5.338305950164795, + 2.439634084701538, + 5.157947063446045, + -0.1652122437953949, + 4.837419033050537, + 1.065048336982727, + 2.7345283031463623, + 4.841624736785889, + 4.121882915496826, + 4.020140171051025, + 4.65635871887207, + 2.718170642852783, + 2.0519216060638428, + -5.222856044769287, + 0.5592376589775085, + 3.365361213684082, + 0.21180520951747894, + 2.4396207332611084, + -0.168130561709404, + 0.6959549188613892, + 2.557208776473999, + -4.870782852172852, + -0.9614514112472534, + -1.3367856740951538, + 4.934432029724121, + 2.217880964279175, + 3.162604808807373, + -4.598219871520996, + 0.5065492987632751, + 4.897907257080078, + 2.606520891189575, + 5.1657633781433105, + -0.591286301612854, + -4.127558708190918, + 0.2627823054790497, + 4.68991231918335, + 1.1018953323364258, + 4.903658390045166, + 2.1969499588012695, + 4.924932479858398, + -5.064455986022949, + -0.18808214366436005, + 5.197934627532959, + 3.13769268989563, + -5.4680938720703125, + 2.236219644546509, + 3.156296968460083, + 0.5617140531539917, + 1.7595769166946411, + -3.136629819869995, + 0.5461055636405945, + 2.951237440109253, + -6.052795886993408, + 0.07759586721658707, + 4.967543601989746, + 4.807677745819092, + 4.727084636688232, + 4.968959331512451, + 2.0494980812072754, + 1.611371397972107, + 0.867186963558197, + 1.2038224935531616, + 7.424896240234375, + 2.237819194793701, + 1.146499752998352, + 4.8438944816589355, + 6.744086265563965, + -4.032275199890137, + -0.15070293843746185, + 4.32798433303833, + -0.9857120513916016, + 0.6673396825790405, + -4.505259990692139, + -0.20449958741664886, + 2.0512490272521973, + 6.0950798988342285, + -0.15016327798366547, + 5.772869110107422, + 0.8016018867492676, + -2.98636794090271, + 1.0190792083740234, + -2.776352643966675, + 6.242586612701416, + -1.2336827516555786, + 1.304807424545288, + -0.26823151111602783, + -5.401467323303223, + -2.2168586254119873, + 1.790359616279602, + -0.3715771734714508, + 7.3444647789001465, + -2.6526482105255127, + 0.550469160079956, + -0.1673431694507599, + 0.9677151441574097, + -0.5982912182807922, + 2.4396321773529053, + -0.9735022783279419, + -0.5724453330039978, + 0.8013267517089844, + 4.2968316078186035, + 4.965913772583008, + -4.14207649230957, + -0.958854615688324, + 2.207848072052002, + 4.397021770477295, + 4.771520614624023, + -0.5689128041267395, + -2.071253538131714, + -4.1096649169921875, + 1.3421775102615356, + -5.818005084991455, + -4.8636980056762695, + 0.5719978213310242, + 0.713057279586792, + 4.962299346923828, + 1.3269661664962769, + 5.03648567199707, + 0.5577100515365601, + -0.5666183233261108, + 4.606432914733887, + 4.816032886505127, + 0.2113383263349533, + 7.049118518829346, + 4.617603778839111, + -4.426548957824707, + 2.9179742336273193, + -4.912374496459961, + -1.3369027376174927, + -0.42551201581954956, + 1.2350519895553589, + -1.964391827583313, + 1.0746006965637207, + -3.3731601238250732, + 0.21939529478549957, + 2.4294207096099854, + -5.2213215827941895, + 4.723667144775391, + 1.8193031549453735, + -0.9681867361068726, + 2.4387028217315674, + 0.5692779421806335, + 2.4118616580963135, + 1.9455655813217163, + 3.2299742698669434, + 2.533686399459839, + 2.2421963214874268, + 2.452453374862671, + 2.238967180252075, + 4.6855058670043945, + 3.7522759437561035, + 2.072413921356201, + 7.060023307800293, + -0.15569409728050232, + 6.0184006690979, + 0.4454742670059204, + -5.3631157875061035, + 5.4132795333862305, + 1.0967118740081787, + 0.7209372520446777, + -5.609560966491699, + -2.818324327468872, + -0.5669602751731873, + 4.071189880371094, + 0.7979661822319031, + -5.320361137390137, + -0.11931989341974258, + -0.9595849514007568, + 1.0911701917648315, + -5.370112419128418, + 0.8192752599716187, + -0.9681893587112427, + 2.1532976627349854, + 1.9717119932174683, + -0.21604683995246887, + -1.0024254322052002, + 2.532884359359741, + 4.636390686035156, + 5.2168498039245605, + -2.352695941925049, + 2.6623642444610596, + -0.5665827989578247, + 6.579907417297363, + 0.8218039870262146, + 0.7901385426521301 + ], + "hoverlabel": { + "namelength": 0 + }, + "mode": "markers", + "marker": { + "color": "#19d3f3", + "opacity": 0.7, + "symbol": "circle" + }, + "x": [ + -0.37070491909980774, + -3.2688329219818115, + -5.3963446617126465, + 2.0244855880737305, + -3.171449661254883, + -4.995485782623291, + -2.7814929485321045, + -3.5632216930389404, + -3.6227340698242188, + -6.170872688293457, + -3.431405782699585, + -4.699724197387695, + -3.580552339553833, + 2.9181742668151855, + -6.002976894378662, + -3.431197166442871, + -0.18654288351535797, + 2.232243061065674, + -0.8730794191360474, + -3.576061964035034, + -3.1289005279541016, + -6.607860088348389, + -2.535661220550537, + -1.7712829113006592, + -0.7033602595329285, + -3.169034242630005, + 1.5306538343429565, + -3.853563070297241, + -3.8648533821105957, + -4.779484748840332, + 1.0548025369644165, + 4.465392589569092, + 1.6351096630096436, + -5.417520999908447, + -2.8658971786499023, + 2.524317502975464, + -5.078507900238037, + -4.319832801818848, + -5.836221694946289, + -2.2532975673675537, + -5.162741184234619, + -3.269873857498169, + -3.8650848865509033, + 0.02673184499144554, + -0.3767971694469452, + -3.169635057449341, + -5.7583184242248535, + -3.126737356185913, + -4.360965728759766, + 2.4114320278167725, + -3.255638599395752, + -1.1424705982208252, + 4.79952335357666, + 1.9512009620666504, + 3.050501585006714, + -5.749743938446045, + 4.202418327331543, + -4.222173690795898, + 4.410865783691406, + -1.065466284751892, + -3.3206586837768555, + 0.03839627280831337, + 2.041247606277466, + 3.5309033393859863, + 2.738636016845703, + 2.6516952514648438, + -5.641282558441162, + -1.156711220741272, + -1.54481840133667, + -5.79075288772583, + -5.815542221069336, + -3.2585606575012207, + 2.6834065914154053, + -3.3144114017486572, + -1.1068360805511475, + -0.5787308812141418, + -4.213079452514648, + 1.4495079517364502, + -6.010429859161377, + -1.0467300415039062, + -2.3097383975982666, + -4.346578598022461, + -1.5500355958938599, + -1.07206392288208, + 2.957427740097046, + -4.903687953948975, + -1.9848624467849731, + -4.630558490753174, + 4.689337730407715, + 2.461083173751831, + -4.866640567779541, + 2.3573226928710938, + -1.7083014249801636, + -5.554337501525879, + 0.11880902200937271, + -5.985771179199219, + 0.3179413676261902, + -4.2182936668396, + 2.996877431869507, + -2.384289026260376, + -4.364353179931641, + -2.7469356060028076, + -5.756377220153809, + -4.723666191101074, + -0.9330641031265259, + -3.2678794860839844, + -0.5316653251647949, + 2.087049722671509, + -2.669721841812134, + -1.881971836090088, + -5.427213191986084, + 1.3933128118515015, + -4.352901458740234, + 0.3257784843444824, + 0.9018670320510864, + 0.49660104513168335, + 2.7016491889953613, + 4.111870288848877, + 0.9052771925926208, + -5.982504367828369, + 2.6973013877868652, + 4.585347652435303, + 0.902923583984375, + 2.219759464263916, + -3.8703818321228027, + -5.707727432250977, + -1.697291612625122, + 4.344358444213867, + -2.3048248291015625, + -4.401340961456299, + -4.356314659118652, + -3.2347795963287354, + -7.1240434646606445, + -1.9094271659851074, + 3.79720401763916, + -1.5741217136383057, + 2.7408363819122314, + -3.245100736618042, + 1.2247364521026611, + 3.515296220779419, + 1.0625337362289429, + -4.4429030418396, + 2.76873517036438, + -3.8727407455444336, + -3.7884011268615723, + -4.54340934753418, + 3.521282434463501, + 1.1805070638656616, + -0.2060965746641159, + -0.5436376333236694, + -6.973118782043457, + -0.213592529296875, + -0.07054930925369263, + -3.892230749130249, + -5.5641326904296875, + -6.464962959289551, + -1.6671361923217773, + 1.165081262588501, + 2.221290111541748, + -0.6546749472618103, + 5.4163031578063965, + -3.127923011779785, + -1.0019272565841675, + -0.7319225668907166, + -1.303419828414917, + -1.326125144958496, + 1.914876103401184, + 0.09735342860221863, + -6.776612281799316, + -5.643983840942383, + -3.3108983039855957, + -1.0963542461395264, + 0.828445553779602, + 3.2315495014190674, + -0.6699680685997009, + -5.069676399230957, + -1.8860043287277222, + -0.5457766056060791, + 0.9050483107566833, + -1.0355507135391235, + -3.0493338108062744, + -0.7262943387031555, + 0.6440380811691284, + -6.173770904541016, + -0.5253303647041321, + 1.6563667058944702, + 3.341437816619873, + -0.5148912072181702, + 4.6111602783203125, + -1.9251697063446045, + -0.441087931394577, + -0.30054351687431335, + -4.266245365142822, + -3.312899112701416, + 4.689280986785889, + -0.15587909519672394, + 5.4943366050720215, + -1.6196130514144897, + -5.105623722076416, + -4.524683952331543, + 5.481297016143799, + -6.070074081420898, + -2.769761562347412, + -6.7255449295043945, + -7.04404878616333, + 1.1621079444885254, + -3.144754648208618, + -1.4525511264801025, + -0.032160524278879166, + -0.200835183262825, + -5.757447242736816, + 1.6562385559082031, + 4.653427600860596, + 1.7922022342681885, + 2.116331100463867, + -4.627471923828125, + 1.508823037147522, + -5.350705623626709, + -4.476149559020996, + 1.592674970626831, + -3.4311752319335938, + -1.1535975933074951, + -3.1690192222595215, + -1.1678611040115356, + -6.843441963195801, + -4.245898723602295, + 1.7164264917373657, + 0.0010989008005708456, + -0.08898157626390457, + 0.668806254863739, + 2.3381221294403076, + 1.4539004564285278, + 1.4432488679885864, + -1.9443027973175049, + -0.5564339756965637, + -3.8913612365722656, + -3.431178331375122, + -3.169093608856201, + -6.663171768188477, + 4.1217780113220215, + 0.06225227937102318, + -4.540151596069336, + -3.864213705062866, + 1.7115107774734497, + 3.355614185333252, + -5.822094440460205, + 0.787483811378479, + -3.39359450340271, + 0.8320444226264954, + 2.2172679901123047, + -5.162675857543945, + -3.130305290222168, + 0.26291391253471375, + -5.986927032470703, + 1.3502705097198486, + -4.7452473640441895, + 1.4067968130111694, + 4.055295467376709, + 2.1203761100769043, + 1.208500623703003, + -1.6142066717147827, + -3.1566884517669678, + -0.7208808064460754, + 1.736862301826477, + 2.6467444896698, + 5.302366256713867, + -3.270663261413574, + 0.3548120856285095, + 2.6824967861175537, + -3.3204188346862793, + 2.236607313156128, + 2.368657112121582, + -5.817616939544678, + 2.019158363342285, + 1.940643548965454, + 0.6890597939491272, + 2.2147061824798584, + -2.7359509468078613, + -4.069775581359863, + -5.117480278015137, + -6.723112106323242, + -2.531696319580078, + 2.2649178504943848, + -2.2273175716400146, + 1.0916030406951904, + -2.1371419429779053, + 4.655168533325195, + -3.1717238426208496, + 2.938180446624756, + -3.308393716812134, + -6.472592830657959, + 0.7861093282699585, + -5.801867961883545, + -2.702242136001587, + -2.578946113586426, + -4.360274314880371, + -5.212457180023193, + -2.7469284534454346, + 3.0927441120147705, + -7.024960041046143, + -1.3774144649505615, + -0.7158127427101135, + -3.566248655319214, + -5.740635395050049, + -5.777310371398926, + 1.7066718339920044, + -3.2396953105926514, + -3.752532482147217, + -5.747265815734863, + -5.978874206542969, + -1.4957648515701294, + -3.2703516483306885, + -3.1682348251342773, + -2.319779872894287, + -4.628747463226318, + -3.4311788082122803, + -3.3014657497406006, + -3.1278200149536133, + -2.7475149631500244, + 0.20133931934833527, + -4.927865028381348, + 0.8815134763717651, + -4.545128345489502, + 3.309628963470459, + 0.1842341125011444, + 0.8031052947044373, + -4.627690315246582, + 4.0038347244262695, + 0.2542107105255127, + -1.1384625434875488, + 2.115166664123535, + 0.717854917049408, + -3.260179281234741, + -6.693642616271973, + -5.100831031799316, + -1.1927943229675293, + 2.321950912475586, + -3.2918570041656494, + -4.629331588745117, + 0.6279463171958923, + -6.8817057609558105, + -3.899496078491211, + -5.745904445648193, + 3.5962977409362793, + 0.5990667939186096, + -6.1680216789245605, + 4.480371952056885, + -3.868562936782837, + -0.4640786349773407, + -1.5068731307983398, + 4.129516124725342, + -4.62164306640625, + -0.6280629634857178, + -3.8864212036132812, + -1.1559617519378662, + 1.437741756439209, + 0.8061985969543457, + 0.5844904780387878, + -4.533249855041504, + -1.1278290748596191, + -3.2662346363067627, + -1.14369797706604, + -3.2566816806793213, + -0.6524250507354736, + 4.793200492858887, + 2.356734275817871, + 4.444393157958984, + 2.3463680744171143, + 2.841430902481079, + 5.491816520690918, + -2.8424251079559326, + -5.743363380432129, + -4.356561183929443, + -4.635774612426758, + -6.060843467712402, + 1.2698113918304443, + -5.2416672706604, + -1.93868887424469, + -1.1164627075195312, + 2.1029586791992188, + -1.319050669670105, + -4.628289699554443, + -0.12679824233055115, + -2.7584900856018066, + 1.5480304956436157, + -4.397653102874756, + -4.542132377624512, + -1.9574246406555176, + 1.6077978610992432, + -5.142321586608887, + -4.528102397918701, + 4.1230387687683105, + 1.1799637079238892, + -0.7592023015022278, + 5.423253059387207, + 4.7660417556762695, + 3.3625597953796387, + -5.118302345275879, + -4.027073860168457, + 3.7844126224517822, + -4.627655029296875, + -5.532456874847412, + -6.6641526222229, + -2.788970708847046 + ], + "z": [ + -8.663113594055176, + -7.452901363372803, + -5.811242580413818, + -6.60654878616333, + -8.394427299499512, + -6.615955352783203, + -17.15903091430664, + -10.961414337158203, + -2.5945372581481934, + -3.683537721633911, + -5.599771499633789, + -10.08835220336914, + -11.034045219421387, + -5.281725883483887, + -3.917182445526123, + -5.599156379699707, + -19.508684158325195, + -6.383503437042236, + -9.615222930908203, + -11.007597923278809, + -9.37817668914795, + -3.1428191661834717, + -4.856026649475098, + -10.150952339172363, + -2.867065191268921, + -8.429777145385742, + -4.630553245544434, + -11.744125366210938, + -15.861108779907227, + -5.290316581726074, + -5.499599456787109, + -3.9905805587768555, + -2.8095569610595703, + -5.837981224060059, + -10.14289665222168, + -4.133089542388916, + -6.731313705444336, + -3.401162624359131, + -4.48196268081665, + -14.226092338562012, + -6.18388557434082, + -7.450872898101807, + -11.774657249450684, + -8.5352783203125, + -3.7335081100463867, + -8.42320442199707, + -5.56865119934082, + -9.399219512939453, + -15.09870719909668, + -5.798282623291016, + -16.606611251831055, + -9.317185401916504, + -21.89504051208496, + -6.694100379943848, + -21.322797775268555, + -5.196463108062744, + -22.03750228881836, + -12.540238380432129, + -22.086332321166992, + -9.970337867736816, + -10.231633186340332, + -3.0706140995025635, + -21.007787704467773, + -21.852210998535156, + -21.281511306762695, + -21.372631072998047, + -5.981438636779785, + -18.772672653198242, + -18.462717056274414, + -5.43339729309082, + -5.5604166984558105, + -16.607547760009766, + -21.28829002380371, + -10.21694278717041, + -9.343226432800293, + -8.892354011535645, + -12.5219144821167, + -20.649658203125, + -4.001999378204346, + -9.568469047546387, + -17.721330642700195, + -15.092238426208496, + -18.458402633666992, + -9.859110832214355, + -21.577190399169922, + -4.292782306671143, + -18.058324813842773, + -14.1743745803833, + -21.61574363708496, + -6.010176181793213, + -4.127090930938721, + -21.15142059326172, + -5.894228458404541, + -5.936951160430908, + -8.196866035461426, + -5.355832576751709, + -8.078011512756348, + -12.531965255737305, + -21.27772331237793, + -15.153217315673828, + -15.096023559570312, + -17.2135066986084, + -5.853236675262451, + -10.136187553405762, + -4.499351978302002, + -7.4634575843811035, + -8.862069129943848, + -5.643404006958008, + -4.795627593994141, + -18.158132553100586, + -6.062032222747803, + -20.61174201965332, + -15.092745780944824, + -6.4207940101623535, + -20.273361206054688, + -7.889683246612549, + -5.501680374145508, + -21.4720516204834, + -20.275094985961914, + -5.337543487548828, + -5.576319694519043, + -3.522629976272583, + -20.274097442626953, + -2.913334846496582, + -11.78633975982666, + -4.855090141296387, + -5.8809709548950195, + -21.535316467285156, + -17.727113723754883, + -8.956610679626465, + -15.108762741088867, + -16.049880981445312, + -1.2152012586593628, + -4.976322174072266, + -21.724225997924805, + -8.847406387329102, + -21.27269744873047, + -16.031063079833984, + -7.290857315063477, + -4.4873247146606445, + -7.505489349365234, + -15.010964393615723, + -5.661792278289795, + -11.78758430480957, + -8.506937026977539, + -13.332112312316895, + -21.86165428161621, + -20.461198806762695, + -7.893319129943848, + -3.743596315383911, + -1.7716113328933716, + -19.48824119567871, + -3.6740028858184814, + -15.825268745422363, + -5.85974645614624, + -0.9331120848655701, + -5.8352251052856445, + -7.1787309646606445, + -2.8926737308502197, + -3.2460224628448486, + -21.754798889160156, + -9.395719528198242, + -4.420779228210449, + -4.114004135131836, + -10.2097806930542, + -10.159652709960938, + -6.755434989929199, + -19.714962005615234, + -2.238201856613159, + -5.926126956939697, + -10.2149019241333, + -10.009421348571777, + -7.495488166809082, + -3.325537919998169, + -8.981019020080566, + -6.740614414215088, + -18.15648078918457, + -8.211318969726562, + -20.27492904663086, + -5.7680583000183105, + -6.779713153839111, + -4.712094783782959, + -6.96915864944458, + -1.0601266622543335, + -3.7010090351104736, + -6.995625972747803, + -4.816271781921387, + -19.272977828979492, + -3.5411505699157715, + -18.1162166595459, + -3.5103766918182373, + -8.877392768859863, + -5.490816116333008, + -10.214690208435059, + -21.617658615112305, + -19.53152847290039, + -21.673620223999023, + -4.367945671081543, + -6.50662088394165, + -13.284725189208984, + -21.692157745361328, + -5.58195161819458, + -0.6704294681549072, + -2.2471365928649902, + -1.313328504562378, + -7.29465389251709, + 0.923859179019928, + -9.727867126464844, + -7.733980178833008, + -19.49873161315918, + -5.831502914428711, + -22.206979751586914, + -4.098930358886719, + -5.662898063659668, + -5.501450061798096, + -14.185585975646973, + -7.27233362197876, + -4.139002799987793, + -5.476692199707031, + -6.985534191131592, + -5.599438190460205, + -5.294553279876709, + -8.423441886901855, + -6.066525936126709, + -1.5745184421539307, + -4.840304851531982, + -6.3796844482421875, + -8.572232246398926, + -8.671597480773926, + -7.808551788330078, + -3.0037620067596436, + -20.651973724365234, + -7.279044151306152, + -9.740174293518066, + -9.262371063232422, + -15.824820518493652, + -5.599451065063477, + -8.42704963684082, + -2.5656750202178955, + -21.453155517578125, + -6.307552814483643, + -13.328841209411621, + -11.768864631652832, + -6.865974426269531, + -21.48469352722168, + -3.6387274265289307, + -7.652405261993408, + -16.431644439697266, + -7.1910505294799805, + -2.989384889602661, + -6.594914436340332, + -9.41611099243164, + -8.170642852783203, + -4.192357540130615, + -5.603940010070801, + -10.180205345153809, + -7.4084391593933105, + -21.85839080810547, + -6.425630569458008, + -4.472840309143066, + -5.742839336395264, + 1.3784838914871216, + -9.413110733032227, + -6.855988502502441, + -21.395477294921875, + -21.83491325378418, + -7.442481517791748, + -19.89724349975586, + -3.0632164478302, + -16.506698608398438, + -3.336191415786743, + -6.118470668792725, + -4.686434745788574, + -6.709057807922363, + -6.048812389373779, + -6.323862075805664, + -6.531671524047852, + -0.691574215888977, + -3.1206209659576416, + -11.928838729858398, + -2.7726643085479736, + -3.2537200450897217, + -21.104515075683594, + -14.094245910644531, + -7.340435028076172, + -3.7111942768096924, + -4.172500133514404, + -8.397875785827637, + -3.7386300563812256, + -10.199318885803223, + -2.979869842529297, + -7.139244556427002, + -5.160993576049805, + -0.5579833388328552, + -4.613835334777832, + -15.097755432128906, + -6.180325031280518, + -17.21348762512207, + -3.251018762588501, + -1.3179395198822021, + -9.614300727844238, + -3.4834389686584473, + -10.985844612121582, + -1.2856794595718384, + -5.29640531539917, + -6.671395301818848, + -16.03058624267578, + -2.5911502838134766, + -5.50637674331665, + -5.577210426330566, + -9.66108512878418, + -7.453004837036133, + -8.427569389343262, + -17.709657669067383, + -14.112767219543457, + -5.599441051483154, + -10.18998908996582, + -9.36706256866455, + -17.212905883789062, + -8.398995399475098, + -6.5749430656433105, + -6.798600196838379, + -13.331466674804688, + -21.503210067749023, + -8.108868598937988, + -7.41459846496582, + -14.193684577941895, + -3.735654354095459, + -8.162774085998535, + -18.786542892456055, + -6.494684219360352, + -2.947492837905884, + -16.605131149291992, + -2.4957358837127686, + -6.671143531799316, + -18.748584747314453, + -4.618483066558838, + -16.527366638183594, + -14.190191268920898, + -7.990166187286377, + -1.466429352760315, + -15.807122230529785, + -5.703986644744873, + -4.651555061340332, + -7.842545986175537, + -3.0627079010009766, + -4.671318054199219, + -11.782312393188477, + -3.5599615573883057, + -18.494569778442383, + -3.6646604537963867, + -9.9858980178833, + -8.954536437988281, + -15.83378791809082, + -9.867314338684082, + -7.326427936553955, + -7.69197416305542, + -20.04892349243164, + -13.295835494995117, + -9.927664756774902, + -16.60236930847168, + -9.938685417175293, + -1.731528639793396, + -9.359153747558594, + -21.90872573852539, + -21.150917053222656, + -22.070842742919922, + -21.148880004882812, + -5.012885570526123, + -21.676288604736328, + 0.016534876078367233, + -5.685157775878906, + -15.106029510498047, + -5.983838081359863, + -3.84428334236145, + -6.271881103515625, + -5.534045696258545, + -18.1026668548584, + -5.050970554351807, + -5.968332767486572, + -9.556039810180664, + -14.197012901306152, + -8.53219985961914, + -17.19886016845703, + -7.212345123291016, + -15.054930686950684, + -13.332160949707031, + -18.083236694335938, + -7.106440544128418, + -12.149538040161133, + -13.285502433776855, + -21.746976852416992, + -20.460660934448242, + -4.187128067016602, + -3.237865686416626, + -21.93344497680664, + -4.732480525970459, + -6.47340202331543, + -10.500948905944824, + -21.804521560668945, + -14.19480037689209, + -5.903923988342285, + -2.4874417781829834, + -17.14113998413086 + ], + "type": "scatter3d" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "layout": { + "title": { + "text": "3d TSNE Plot for Topic Model" + }, + "scene": { + "domain": { + "y": [ + 0, + 1 + ], + "x": [ + 0, + 1 + ] + }, + "zaxis": { + "title": { + "text": "2" + } + }, + "xaxis": { + "title": { + "text": "0" + } + }, + "yaxis": { + "title": { + "text": "1" + } + } + }, + "height": 800, + "width": 900, + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "legend": { + "tracegroupgap": 0 + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "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": 542 + }, + "id": "UkMHE1gR7UFY", + "outputId": "22c22cc9-6a70-472c-a2d0-186cca68fc60" + }, + "source": [ + "plot_model(lda, plot='topic_distribution',topic_num = 4)\n" + ], + "id": "UkMHE1gR7UFY", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "textposition": "auto", + "hovertemplate": "Topic=%{x}
Documents=%{y}
Keyword=%{customdata[0]}", + "showlegend": false, + "legendgroup": "", + "name": "", + "yaxis": "y", + "customdata": [ + [ + "game, link, world, minute, character, go, final, first, time, take" + ], + [ + "ball, shoot, good, go, play, basketball, year, hand, jump, court" + ], + [ + "play, game, basketball, go, good, people, want, really, start, say" + ], + [ + "shoot, attempt, shot, second, point, high, tank, game, season, leave" + ], + [ + "game, new, time, player, good, overwatch, year, play, see, may" + ], + [ + "team, player, game, play, year, season, stat, win, good, school" + ] + ], + "y": [ + 128, + 262, + 557, + 140, + 223, + 403 + ], + "hoverlabel": { + "namelength": 0 + }, + "offsetgroup": "", + "xaxis": "x", + "marker": { + "color": "#636efa" + }, + "x": [ + "Topic 0", + "Topic 1", + "Topic 2", + "Topic 3", + "Topic 4", + "Topic 5" + ], + "alignmentgroup": "True", + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "yaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "x", + "title": { + "text": "Documents" + } + }, + "title": { + "text": "Document Distribution by Topics" + }, + "barmode": "relative", + "xaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "y", + "title": { + "text": "Topic" + } + }, + "legend": { + "tracegroupgap": 0 + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "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": 1000 + }, + "id": "JBaDxwhT82oy", + "outputId": "063d28c2-7d2e-4826-fe9d-43c4c5f87e92" + }, + "source": [ + "plot_model(lda, plot='topic_model')\n", + "plot_model(lda, plot='wordcloud', topic_num = 'Topic 5')\n", + "plot_model(lda, plot='frequency', topic_num = 'Topic 5')\n" + ], + "id": "JBaDxwhT82oy", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "PreparedData(topic_coordinates= x y topics cluster Freq\n", + "topic \n", + "4 -0.084467 -0.073092 1 1 26.586656\n", + "2 -0.062320 0.142625 2 1 25.038237\n", + "5 0.124700 -0.197664 3 1 18.918841\n", + "1 0.093410 0.191072 4 1 11.615811\n", + "3 0.126536 0.007160 5 1 9.144265\n", + "0 -0.197860 -0.070100 6 1 8.696191, topic_info= Term Freq Total Category logprob loglift\n", + "341 team 992.000000 992.000000 Default 30.0000 30.0000\n", + "256 player 773.000000 773.000000 Default 29.0000 29.0000\n", + "1086 shoot 294.000000 294.000000 Default 28.0000 28.0000\n", + "4800 basketball 442.000000 442.000000 Default 27.0000 27.0000\n", + "3865 ball 275.000000 275.000000 Default 26.0000 26.0000\n", + "... ... ... ... ... ... ...\n", + "96 part 14.123312 58.030505 Topic6 -6.0269 1.0291\n", + "42 second 14.847208 128.967189 Topic6 -5.9769 0.2805\n", + "256 player 16.941607 773.589191 Topic6 -5.8450 -1.3790\n", + "7 good 16.355057 535.383835 Topic6 -5.8802 -1.0462\n", + "106 see 14.630849 311.287455 Topic6 -5.9916 -0.6153\n", + "\n", + "[459 rows x 6 columns], token_table= Topic Freq Term\n", + "term \n", + "4282 2 0.902822 abuse\n", + "2859 1 0.018209 advice\n", + "2859 2 0.801194 advice\n", + "2859 4 0.091045 advice\n", + "2859 5 0.072836 advice\n", + "... ... ... ...\n", + "294 2 0.182399 year\n", + "294 3 0.414543 year\n", + "294 4 0.159599 year\n", + "294 5 0.037309 year\n", + "294 6 0.020727 year\n", + "\n", + "[945 rows x 3 columns], R=30, lambda_step=0.01, plot_opts={'xlab': 'PC1', 'ylab': 'PC2'}, topic_order=[5, 3, 6, 2, 4, 1])" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + } + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "name": "count", + "text": "", + "y": [ + 659, + 362, + 340, + 239, + 188, + 183, + 175, + 131, + 122, + 85, + 84, + 75, + 75, + 73, + 73, + 66, + 64, + 61, + 56, + 56, + 56, + 54, + 52, + 51, + 51, + 51, + 50, + 50, + 49, + 48, + 47, + 47, + 46, + 45, + 45, + 44, + 44, + 43, + 43, + 43, + 41, + 41, + 41, + 40, + 40, + 39, + 39, + 39, + 39, + 36, + 36, + 35, + 35, + 34, + 33, + 32, + 32, + 31, + 31, + 30, + 30, + 29, + 29, + 29, + 29, + 28, + 28, + 28, + 28, + 28, + 27, + 27, + 27, + 26, + 26, + 26, + 26, + 26, + 26, + 25, + 25, + 25, + 25, + 25, + 25, + 24, + 24, + 24, + 24, + 24, + 24, + 24, + 23, + 23, + 22, + 22, + 22, + 21, + 21, + 21 + ], + "marker": { + "color": "rgba(255, 153, 51, 0.6)", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": 1 + } + }, + "x": [ + "team", + "game", + "player", + "play", + "season", + "stat", + "year", + "win", + "good", + "point", + "go", + "time", + "say", + "look", + "last", + "total", + "start", + "source", + "bad", + "basketball", + "playoff", + "laker", + "see", + "warrior", + "minute", + "far", + "average", + "even", + "first", + "trade", + "top", + "assist", + "take", + "big", + "number", + "come", + "may", + "draft", + "defense", + "points_rebounds_assist", + "final", + "back", + "contract", + "league", + "leader", + "great", + "high", + "record", + "seem", + "clipper", + "eastern", + "right", + "career", + "shoot", + "fan", + "lose", + "current", + "quarter", + "give", + "low", + "buck", + "lead", + "offense", + "people", + "reddit_stream_must_click", + "defensive", + "many", + "net", + "score", + "case", + "miss", + "need", + "pick", + "end", + "ad", + "guy", + "sixer", + "want", + "pretty", + "blk_pf_pt", + "sign", + "least", + "thing", + "really", + "show", + "better", + "pm_pacific_box_score", + "school", + "leave", + "lot", + "new", + "pass", + "king", + "level", + "second", + "use", + "run", + "change", + "consider", + "role" + ], + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "title": { + "text": "Topic 5: Top 100 words after removing stop words", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "Count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "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": 1000 + }, + "id": "3nXH69857UJe", + "outputId": "b23704b1-d652-4634-b780-e886a1f18866" + }, + "source": [ + "plot_model(lda, plot='bigram', topic_num = 'Topic 5')\n", + "plot_model(lda, plot='trigram', topic_num = 'Topic 5')\n", + "plot_model(lda, plot='distribution', topic_num = 'Topic 5')\n", + "plot_model(lda, plot='sentiment', topic_num = 'Topic 5')" + ], + "id": "3nXH69857UJe", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "name": "count", + "text": "", + "y": [ + 69, + 63, + 61, + 59, + 41, + 39, + 34, + 34, + 34, + 33, + 33, + 31, + 30, + 29, + 26, + 25, + 24, + 24, + 22, + 21, + 17, + 17, + 16, + 14, + 14, + 14, + 11, + 10, + 10, + 10, + 9, + 9, + 9, + 9, + 9, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 7, + 7, + 7, + 7, + 7, + 7, + 7, + 7, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 6, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 5, + 4, + 4 + ], + "marker": { + "color": "rgba(255, 153, 51, 0.6)", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": 1 + } + }, + "x": [ + "player stat", + "team stat", + "game team", + "stat team", + "team play", + "team team", + "eastern game", + "team leader", + "leader team", + "team points_rebounds_assist", + "total team", + "team total", + "play play", + "last year", + "team player", + "last season", + "win win", + "game game", + "player player", + "team biggest_lead_longest_run", + "game summary_location", + "good player", + "play nba_com", + "team pts_fg_fg_ft", + "reddit_stream_must_click link_comment_page", + "year old", + "reddit_stream_must_click game", + "pre game", + "win team", + "game summary_location_staples_center", + "point game", + "assist player", + "role player", + "biggest_lead_longest_run team", + "game season", + "far season", + "career high", + "basketball player", + "start season", + "clipper team", + "come back", + "top player", + "play game", + "young player", + "game last", + "game play", + "player league", + "year team", + "approximately year", + "points_rebounds_assist player", + "team good", + "player assist", + "year approximately", + "win rate", + "win game", + "team year", + "summary_location_staples_center team", + "game summary_location_chase_center", + "season average", + "player name", + "individual player", + "lead team", + "play season", + "minute game", + "low career", + "playoff run", + "minute together", + "people say", + "link_comment_page game", + "draft pick", + "far good", + "entire league", + "top team", + "draw eubank", + "undrafted player", + "draft draft", + "first game", + "western conference", + "wilt lose", + "box_scores_nba_yahoo game", + "point assist", + "player say", + "phoenix_suns team", + "percentile entire", + "first year", + "star player", + "source say", + "outscore opponent", + "opponent point", + "miss game", + "game win", + "golden_state_warrior player", + "good defensive", + "queue time", + "good record", + "quarter minute", + "portland_trail_blazer los_angeles_clipper", + "san_antonio_spur team", + "team cap", + "enemy team" + ], + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "title": { + "text": "Topic 5: Top 100 bigrams after removing stop words", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "Count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "name": "count", + "text": "", + "y": [ + 59, + 34, + 33, + 32, + 27, + 25, + 22, + 19, + 19, + 19, + 17, + 15, + 14, + 14, + 14, + 13, + 12, + 11, + 10, + 9, + 9, + 8, + 7, + 7, + 7, + 7, + 7, + 6, + 6, + 6, + 6, + 5, + 5, + 5, + 5, + 5, + 5, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3 + ], + "marker": { + "color": "rgba(255, 153, 51, 0.6)", + "line": { + "color": "rgba(255, 153, 51, 1.0)", + "width": 1 + } + }, + "x": [ + "team stat team", + "team leader team", + "leader team points_rebounds_assist", + "game team play", + "team play play", + "total team stat", + "team total team", + "eastern game game", + "game game team", + "win win win", + "team player stat", + "stat team team", + "stat team pts_fg_fg_ft", + "play play nba_com", + "stat team player", + "player player player", + "game team total", + "team team biggest_lead_longest_run", + "game team stat", + "team biggest_lead_longest_run team", + "biggest_lead_longest_run team leader", + "assist player player", + "team points_rebounds_assist player", + "points_rebounds_assist player stat", + "team team leader", + "team team stat", + "team team team", + "reddit_stream_must_click game team", + "game summary_location_staples_center team", + "player player name", + "year approximately year", + "golden_state_warrior player stat", + "percentile entire league", + "outscore opponent point", + "quarter minute together", + "approximately year approximately", + "summary_location_staples_center team total", + "reddit_stream_must_click link_comment_page game", + "draw eubank devin", + "team total clipper", + "game summary_location team", + "team pts_fg_fg_ft clipper", + "league low career", + "game summary_location fedexforum", + "total clipper team", + "game center_us_pm_central game", + "percentage percentile entire", + "entire league low", + "eastern game center_us_pm_central", + "play play pm_pacific_box_score", + "team pts_fg_fg_ft team", + "summary_location team stat", + "clipper team stat", + "pm_central game team", + "pts_fg_fg_ft player stat", + "portland_trail_blazer los_angeles_clipper team", + "simon cody snell", + "caper team total", + "center_us_pm_central game team", + "team pts_fg_fg_ft player", + "box_scores_nba_yahoo game summary_location", + "total team player", + "total team team", + "game arena game", + "eastern game arena", + "game last season", + "biggest_lead_longest_run golden_state_warrior team", + "cha hornet blk_pf_pt", + "away score home", + "warrior reddit_stream_must_click game", + "tip away score", + "thread index tip", + "arena game team", + "last season average", + "game thread index", + "golden_state_warrior team leader", + "reddit_stream_must_click game summary_location_chase_center", + "score home pgt", + "pts_fg_fg_ft team biggest_lead_longest_run", + "portland_trail_blazer phoenix_suns team", + "player stat mil_milwaukee_buck", + "player stat ind_indiana_pacer", + "player stat dal", + "player stat cha_charlotte_hornet", + "stat buck blk_pf_pt", + "player stat buck", + "player stat bkn_brooklyn_net", + "stat cha hornet", + "play nba_com pacer", + "play mkebuck pm_pacific_box_score", + "play heat pm_pacific_box_score", + "team biggest_lead_longest_run golden_state_warrior", + "team points_rebounds_assist giannis_antetokounmpo", + "nba_com pacer pm_pacific_box_score", + "lose lose situation", + "los_angeles_clipper player stat", + "rocket mortgage fieldhouse", + "jazz blk_pf_pt rudy_gobert_donovan_mitchell", + "index tip away", + "player stat cha" + ], + "type": "bar", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "title": { + "text": "Topic 5: Top 100 trigrams after removing stop words", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "Count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "opacity": 0.8, + "name": "post", + "histnorm": "", + "nbinsx": 100, + "histfunc": "count", + "marker": { + "color": "rgba(255, 153, 51, 1.0)", + "line": { + "color": "#000000", + "width": 1.3 + } + }, + "x": [ + 4, + 24, + 1, + 54, + 29, + 99, + 7, + 205, + 47, + 20, + 30, + 27, + 20, + 6, + 26, + 7, + 4, + 3, + 87, + 16, + 26, + 5, + 15, + 33, + 51, + 120, + 10, + 68, + 23, + 10, + 66, + 11, + 99, + 11, + 36, + 23, + 53, + 63, + 8, + 41, + 13, + 22, + 8, + 14, + 7, + 11, + 27, + 54, + 13, + 11, + 33, + 27, + 7, + 9, + 5, + 36, + 27, + 65, + 54, + 22, + 27, + 22, + 20, + 30, + 31, + 12, + 13, + 36, + 30, + 52, + 31, + 29, + 26, + 24, + 23, + 28, + 127, + 35, + 69, + 21, + 4, + 18, + 3, + 15, + 10, + 20, + 24, + 15, + 10, + 11, + 14, + 10, + 12, + 17, + 8, + 18, + 30, + 16, + 9, + 17, + 18, + 10, + 13, + 21, + 12, + 10, + 17, + 17, + 19, + 12, + 10, + 11, + 9, + 16, + 14, + 13, + 14, + 15, + 16, + 11, + 11, + 11, + 15, + 7, + 33, + 13, + 30, + 31, + 8, + 91, + 32, + 40, + 37, + 32, + 39, + 27, + 21, + 5, + 31, + 35, + 31, + 21, + 39, + 78, + 16, + 7, + 1, + 10, + 44, + 21, + 9, + 42, + 32, + 23, + 14, + 33, + 28, + 43, + 5, + 25, + 145, + 46, + 35, + 32, + 61, + 4, + 66, + 41, + 20, + 22, + 15, + 99, + 13, + 11, + 16, + 57, + 9, + 12, + 15, + 16, + 11, + 41, + 7, + 20, + 34, + 158, + 26, + 301, + 66, + 21, + 39, + 12, + 135, + 25, + 15, + 76, + 22, + 17, + 18, + 67, + 73, + 34, + 82, + 24, + 7, + 38, + 63, + 438, + 14, + 40, + 3, + 19, + 197, + 22, + 19, + 14, + 50, + 37, + 21, + 20, + 39, + 21, + 93, + 5, + 141, + 25, + 8, + 9, + 20, + 13, + 13, + 13, + 8, + 8, + 12, + 15, + 11, + 17, + 25, + 13, + 16, + 10, + 9, + 21, + 17, + 11, + 4, + 13, + 9, + 18, + 17, + 8, + 34, + 38, + 5, + 29, + 34, + 31, + 18, + 31, + 151, + 25, + 10, + 239, + 36, + 25, + 21, + 18, + 25, + 10, + 19, + 37, + 19, + 49, + 19, + 51, + 27, + 16, + 28, + 14, + 8, + 32, + 43, + 31, + 23, + 43, + 2, + 31, + 33, + 22, + 68, + 59, + 42, + 15, + 28, + 13, + 7, + 38, + 35, + 42, + 16, + 35, + 13, + 39, + 18, + 11, + 5, + 4, + 14, + 57, + 14, + 29, + 9, + 33, + 11, + 37, + 17, + 16, + 13, + 28, + 24, + 24, + 13, + 14, + 33, + 11, + 9, + 24, + 9, + 36, + 26, + 17, + 119, + 40, + 35, + 10, + 13, + 21, + 125, + 23, + 15, + 39, + 40, + 30, + 38, + 30, + 10, + 21, + 4, + 16, + 30, + 1, + 12, + 61, + 8, + 14, + 2, + 26, + 1, + 3, + 19, + 37, + 34, + 31, + 6, + 14, + 2, + 4, + 4, + 30, + 70, + 30, + 4, + 5, + 18, + 3, + 21, + 11, + 3, + 2, + 3, + 24, + 12, + 5, + 20, + 17, + 6, + 2, + 106, + 5, + 28, + 12, + 7, + 37, + 14, + 30, + 12, + 49, + 1, + 12, + 1464, + 3, + 6, + 6 + ], + "type": "histogram", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "word count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "title": { + "text": "Topic 5: Word Count Distribution", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "barmode": "overlay", + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "opacity": 0.8, + "name": "post", + "histnorm": "", + "nbinsx": 50, + "histfunc": "count", + "marker": { + "color": "rgba(255, 153, 51, 1.0)", + "line": { + "color": "#000000", + "width": 1.3 + } + }, + "x": [ + 0.1, + 0.03333333333333333, + 0, + 0.17596153846153847, + -0.21851851851851853, + -0.009226190476190471, + 0, + 0.047101806239737275, + 0.04682539682539682, + 0.325, + -0.5205357142857143, + -0.09464285714285715, + 0.16666666666666666, + 0.5, + -0.09083333333333335, + -0.5, + 0, + -0.05714285714285716, + 0.03947368421052638, + 0, + 0.37714285714285717, + 0.7, + 0.39, + -0.024074074074074085, + -0.014218559218559237, + 0.0522290881161849, + 0.65, + 0.01931818181818182, + 0.37916666666666665, + -0.16249999999999998, + 0.13121212121212122, + 0, + 0.13063603063603063, + 0.2333333333333333, + 0.022000000000000002, + 0.12821428571428573, + 0.17352564102564103, + -0.39999999999999997, + 0.8, + 0.15133928571428573, + 0.0375, + 0.3642857142857143, + -0.2357142857142857, + -0.2, + -0.15, + -0.4, + -0.049999999999999975, + -0.08333333333333333, + 0.21666666666666667, + 0.3375, + -0.30000000000000004, + -0.11428571428571428, + 0, + -0.2, + 0.3107142857142857, + -0.4000000000000001, + -0.12638888888888888, + 0.05914772727272727, + -0.1999999999999999, + -0.17142857142857143, + -0.30000000000000004, + -0.16666666666666666, + 0.08541666666666668, + 0.375, + 0.019999999999999997, + -0.16666666666666666, + 0.43333333333333335, + -0.04166666666666667, + 0.06999999999999999, + 0.03663911845730031, + 0.0888888888888889, + 0.2333333333333333, + 0.0625, + -0.09, + -0.4, + 0.33999999999999997, + 0.08309937611408202, + -0.07777777777777778, + 0.13857142857142857, + 0.20138888888888887, + -0.15, + 0.09999999999999998, + 0, + 0.13333333333333333, + -0.4, + 0, + -0.052777777777777764, + -0.11250000000000002, + 0.0555555555555556, + -0.2, + 0.12, + -0.4, + -0.10000000000000002, + 0.3, + 0, + 0, + 0.06666666666666672, + 0.14999999999999997, + -0.21250000000000002, + 0.11666666666666665, + -0.2, + -0.4, + 0.15416666666666667, + -0.08333333333333336, + 0.07499999999999998, + 0.5, + -0.2, + 0.6666666666666666, + 0.0625, + 0, + -0.4, + -0.4, + -0.12000000000000001, + -0.2, + -0.025000000000000022, + -0.05000000000000001, + -0.20000000000000004, + -0.012499999999999956, + 0.24000000000000005, + -0.2, + -0.2, + -0.2, + -0.4, + -0.4, + 0.36875, + 0.125, + -0.4000000000000001, + -0.4000000000000001, + 0.5, + 0.40833333333333344, + -0.4000000000000001, + -0.30000000000000004, + -0.22000000000000003, + -0.28, + -0.30000000000000004, + -0.4000000000000001, + 0.22879406307977734, + -0.3333333333333333, + -0.30000000000000004, + -0.30000000000000004, + -0.30000000000000004, + -0.4000000000000001, + -0.4000000000000001, + 0.3, + 0.004642857142857171, + 0, + 0, + 0.1, + 0.34750000000000003, + 0.5, + 0.3, + -0.0875, + 0.4033333333333333, + -0.09999999999999998, + -0.17916666666666667, + 0.02250000000000003, + 0.3375, + 0.06666666666666667, + 0, + 0.22142857142857145, + 0.19600313479623827, + 0.0613756613756614, + -0.21319444444444444, + 0.5387755102040817, + -0.0375151515151515, + 0, + -0.028571428571428574, + 0.07277777777777779, + -0.1, + 0.23571428571428574, + 0.55, + 0.022058823529411766, + 0, + -0.35, + -0.2, + 0.109375, + -0.2, + -0.5, + 0.29523809523809524, + 0.15277777777777773, + 0.30000000000000004, + -0.04374999999999998, + -0.2, + -0.06000000000000001, + -0.30000000000000004, + 0.25859213250517593, + -0.30000000000000004, + 0.052609102609102606, + 0.11782407407407408, + 0.1, + 0.008333333333333331, + 0.225, + 0.10613897596656217, + -0.30000000000000004, + 0.1, + -0.16010165429808282, + 0, + -0.07142857142857144, + 0.4136363636363637, + 0.19444444444444445, + -0.005844155844155849, + 0.08928571428571429, + 0.5659090909090913, + 0.4183333333333333, + 0.5333333333333333, + 0.23662698412698413, + -0.008095238095238098, + 0.18700710231244583, + 0, + 0.15083333333333335, + 0, + -0.23333333333333328, + 0.029392655367231665, + 0.195, + 0.33999999999999997, + 0.2589285714285714, + 0.1577922077922078, + -0.1409090909090909, + -0.1875, + 0.022857142857142843, + 0.04724517906336089, + -0.3208333333333333, + -0.11166666666666665, + 0, + -0.04592198581560281, + -0.3, + 0, + -0.1575757575757576, + -0.0062500000000000056, + -0.36, + 0.8, + -0.2, + 0.2619047619047619, + 0.8, + -0.033333333333333326, + -0.03333333333333335, + -0.2, + -0.2, + -0.2, + 0.28354978354978355, + -0.02499999999999998, + -0.4, + 0.3, + 0.11428571428571428, + -0.1607142857142857, + -0.2, + 0.6, + -0.4, + 0.07500000000000001, + -0.08750000000000002, + 0.1, + -0.30000000000000004, + 0.4666666666666666, + -0.30000000000000004, + -0.2, + -0.30000000000000004, + -0.18000000000000002, + -0.4000000000000001, + -0.26666666666666666, + 0.175, + 0.027173469387755105, + -0.26666666666666666, + -0.3, + 0.16114468864468867, + -0.4000000000000001, + -0.35000000000000003, + -0.22142857142857134, + -0.13333333333333333, + -0.30000000000000004, + 0.8, + -0.008333333333333331, + -0.27435897435897433, + 0.475, + 0.15, + 0.125, + 0.20303030303030303, + 0.23666666666666666, + 0.23333333333333336, + -0.1984126984126984, + 0.1766666666666667, + 0.022222222222222216, + -0.6999999999999998, + 0.2571428571428571, + 0.26, + 0.015625, + 0.21079545454545456, + 0, + 0.45000000000000007, + 0.29000000000000004, + -0.07916666666666666, + 0.1611011904761905, + -0.016666666666666666, + 0.07291666666666666, + -0.18333333333333335, + -0.23877551020408164, + 0.35, + 0, + -0.044444444444444446, + 0.07166666666666666, + 0.4333333333333333, + 0, + 0.17619047619047615, + -0.3499999999999999, + 0.20208333333333334, + 0.2333333333333333, + 0, + 0, + 0, + -0.2, + -0.007223274410774377, + 0.039880952380952385, + 0.24444444444444446, + -0.4, + 0.27532467532467525, + 0.3166666666666667, + 0.05946969696969698, + 0.8, + 0.07569444444444443, + -0.4, + 0.32272727272727275, + 0.41385281385281386, + 0.09666666666666668, + -0.2, + -0.2, + 0.08, + -0.4, + -0.2, + 0.2875, + 0.18000000000000002, + -0.30000000000000004, + -0.4000000000000001, + -0.3, + 0.047087251828631146, + 0.15384615384615385, + -0.4000000000000001, + -0.4, + 0.2619047619047619, + 0.3691428571428571, + 0.22156862745098035, + 0.03333333333333333, + -0.3833333333333333, + -0.0625, + -0.30000000000000004, + -0.30000000000000004, + -0.30000000000000004, + -0.4000000000000001, + -0.4, + 0.079004329004329, + 0, + -0.3, + 0.4133333333333334, + 0, + 0.2833333333333333, + 0.017647058823529422, + 0, + 0.25, + 0, + 0.2416666666666666, + 0, + 0, + 0.06666666666666667, + 0.134375, + 0.03839285714285714, + -0.16249999999999998, + 0.8, + -0.11666666666666668, + 0.8, + 0.04999999999999999, + 0.5, + 0.2339285714285714, + 0.017654320987654314, + 0.23888888888888893, + 0.1, + -0.2, + 0.15999999999999998, + 0.4, + -0.049999999999999996, + -0.08333333333333333, + 0.7, + 0.7, + 0.25, + 0.09500000000000001, + 0.0315, + 0.375, + 0.2375, + 1, + 0.8, + -0.4, + -0.002083333333333326, + 0, + 0.19999999999999998, + -0.15, + 0, + 0.5, + 0.032222222222222215, + 0.11666666666666668, + -0.06714285714285714, + -0.15, + 0.43, + 0.8, + 0.45, + 0.10376244393392406, + 0, + 0, + 0.25 + ], + "type": "histogram", + "orientation": "v" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly", + "linkText": "Export to plot.ly", + "showLink": true + }, + "layout": { + "xaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "polarity", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "title": { + "text": "Topic 5: Sentiment Polarity Distribution", + "font": { + "color": "#4D5663" + } + }, + "paper_bgcolor": "#F5F6F9", + "plot_bgcolor": "#F5F6F9", + "yaxis": { + "tickfont": { + "color": "#4D5663" + }, + "title": { + "text": "count", + "font": { + "color": "#4D5663" + } + }, + "showgrid": true, + "zerolinecolor": "#E1E5ED", + "gridcolor": "#E1E5ED", + "linecolor": "black" + }, + "barmode": "overlay", + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "legend": { + "bgcolor": "#F5F6F9", + "font": { + "color": "#4D5663" + } + } + } + } + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "metadata": { + "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": 681, + "referenced_widgets": [ + "9160c088bf39460da64dbad6bd54bdc0", + "41ce9036c91846fea09a3f4893d2d158", + "7d96941448f44a45853a329dc88d8743", + "024de908ddd9428dafdd3ee7c601ddf7", + "b24a7506146f49f8a20bfa822bb7a961" + ] + }, + "id": "V3_4ceAOXbiP", + "outputId": "dbf8be86-b4a5-459b-8240-9784ae2d1d6e" + }, + "source": [ + "tuned_unsupervised = tune_model(model = 'lda', multi_core = True)" + ], + "id": "V3_4ceAOXbiP", + "execution_count": null, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "9160c088bf39460da64dbad6bd54bdc0", + "version_minor": 0, + "version_major": 2 + }, + "text/plain": [ + "IntProgress(value=0, description='Processing: ', max=25)" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "024de908ddd9428dafdd3ee7c601ddf7", + "version_minor": 0, + "version_major": 2 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Initiated. . . . . . . . . . . . . . . . . .07:20:16
Status. . . . . . . . . . . . . . . . . .Finalizing
Step. . . . . . . . . . . . . . . . . .Evaluating Coherence With 400 Topics
\n", + "
" + ], + "text/plain": [ + " \n", + " \n", + "Initiated . . . . . . . . . . . . . . . . . . 07:20:16\n", + "Status . . . . . . . . . . . . . . . . . . Finalizing\n", + "Step . . . . . . . . . . . . . . . . . . Evaluating Coherence With 400 Topics" + ] + }, + "metadata": {} + }, + { + "output_type": "display_data", + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ], + "application/vnd.plotly.v1+json": { + "data": [ + { + "hovertemplate": "Metric=Coherence
# Topics=%{x}
Score=%{y}", + "showlegend": true, + "legendgroup": "Metric=Coherence", + "name": "Metric=Coherence", + "yaxis": "y", + "hoverlabel": { + "namelength": 0 + }, + "mode": "lines", + "xaxis": "x", + "y": [ + 0.3224465938237828, + 0.3893855426773154, + 0.35397738041320764, + 0.3609949011013329, + 0.3866903686896548, + 0.336285815050198, + 0.35860957411164085, + 0.3350647792649555, + 0.34387884707665894, + 0.3572148033097053 + ], + "x": [ + 2, + 4, + 8, + 16, + 32, + 64, + 100, + 200, + 300, + 400 + ], + "line": { + "color": "#636efa", + "dash": "solid", + "shape": "linear" + }, + "type": "scatter" + } + ], + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "layout": { + "template": { + "layout": { + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "polar": { + "radialaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "bgcolor": "#E5ECF6", + "angularaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "xaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "title": { + "x": 0.05 + }, + "scene": { + "zaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "xaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "ticks": "", + "gridwidth": 2, + "showbackground": true, + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + } + }, + "yaxis": { + "automargin": true, + "title": { + "standoff": 15 + }, + "zerolinewidth": 2, + "ticks": "", + "zerolinecolor": "white", + "gridcolor": "white", + "linecolor": "white" + }, + "annotationdefaults": { + "arrowwidth": 1, + "arrowhead": 0, + "arrowcolor": "#2a3f5f" + }, + "hoverlabel": { + "align": "left" + }, + "ternary": { + "bgcolor": "#E5ECF6", + "baxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "caxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + }, + "aaxis": { + "ticks": "", + "gridcolor": "white", + "linecolor": "white" + } + }, + "mapbox": { + "style": "light" + }, + "hovermode": "closest", + "font": { + "color": "#2a3f5f" + }, + "geo": { + "showland": true, + "landcolor": "#E5ECF6", + "showlakes": true, + "bgcolor": "white", + "subunitcolor": "white", + "lakecolor": "white" + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + } + }, + "data": { + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "surface", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "table": [ + { + "header": { + "line": { + "color": "white" + }, + "fill": { + "color": "#C8D4E3" + } + }, + "cells": { + "line": { + "color": "white" + }, + "fill": { + "color": "#EBF0F8" + } + }, + "type": "table" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "carpet": [ + { + "type": "carpet", + "baxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + }, + "aaxis": { + "minorgridcolor": "white", + "gridcolor": "white", + "linecolor": "white", + "endlinecolor": "#2a3f5f", + "startlinecolor": "#2a3f5f" + } + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmap", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatter3d": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "heatmapgl", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2d", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "bar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar", + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + } + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "histogram2dcontour", + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ] + } + }, + "yaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "x", + "title": { + "text": "Score" + } + }, + "plot_bgcolor": "rgb(245,245,245)", + "title": { + "text": "Coherence Value and # of Topics" + }, + "xaxis": { + "domain": [ + 0, + 1 + ], + "anchor": "y", + "title": { + "text": "# Topics" + } + }, + "legend": { + "tracegroupgap": 0 + } + } + } + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Best Model: Latent Dirichlet Allocation | # Topics: 4 | Coherence: 0.3894\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "99457de6", + "outputId": "2ac9462e-f2d1-4c42-d9ea-ede5ced206ee" + }, + "source": [ + "nltk.download('stopwords')" + ], + "id": "99457de6", + "execution_count": null, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[nltk_data] Downloading package stopwords to\n", + "[nltk_data] /Users/safarji/nltk_data...\n", + "[nltk_data] Unzipping corpora/stopwords.zip.\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "5d1222c1" + }, + "source": [ + "#stop word removal + added words \n", + "stopwords = nltk.corpus.stopwords.words('english')\n", + "added_words=['would','make','also','get','still','way','like','much','nbsp','think','could','well','feel']\n", + "for word in added_words:\n", + " stopwords.append(word)\n", + "def remove_stopwords(text):\n", + " output= [i for i in text if i not in stopwords]\n", + " return output\n", + "df['post']=df.post.map(remove_stopwords)" + ], + "id": "5d1222c1", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "cadadea5", + "outputId": "a8599981-fd24-4f5d-f55a-53f4eed49a35" + }, + "source": [ + "nltk.download('wordnet')" + ], + "id": "cadadea5", + "execution_count": null, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "[nltk_data] Downloading package wordnet to /Users/safarji/nltk_data...\n", + "[nltk_data] Unzipping corpora/wordnet.zip.\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "6f5d076d" + }, + "source": [ + "\n", + "#lemmatization\n", + "wordnet_lemmatizer = WordNetLemmatizer()\n", + "def lemmatizer(text):\n", + " lemm_text = [wordnet_lemmatizer.lemmatize(word) for word in text]\n", + " return lemm_text\n", + "df['post']=df['post'].apply(lambda x:lemmatizer(x))" + ], + "id": "6f5d076d", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "57f3efe1" + }, + "source": [ + "# remvoe punctuation\n", + "def listToString(s): \n", + " \n", + " # initialize an empty string\n", + " str1 = \" \" \n", + " \n", + " # return string \n", + " return (str1.join(s))\n", + "\n", + "\n", + "df['post']=df.post.map(listToString)\n", + "punc_lower = lambda x: re.sub('[%s]' % re.escape(string.punctuation), ' ', x.lower())\n", + "df['post']=df.post.map(punc_lower)\n", + "\n", + "#removePunc=lambda x:x.translate(str.maketrans('','',string.punctuation))\n", + "#df['post']=df.post.map(removePunc)\n" + ], + "id": "57f3efe1", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "02697d05" + }, + "source": [ + "cv1 = CountVectorizer()\n", + "c= cv1.fit_transform(df.post)" + ], + "id": "02697d05", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "062472c8", + "outputId": "262e3494-805b-47d1-b7c9-f879c1dcb6c8" + }, + "source": [ + "pd.DataFrame(c.toarray(), columns=cv1.get_feature_names()).head()\n", + "#pd.DataFrame(c.toarray(),index=nba['post'], columns=cv1.get_feature_names()).head()" + ], + "id": "062472c8", + "execution_count": null, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aaaaaronaauababaabandonabandonedabandoningabdelabducted...zydrunasálvaroďaysšarićštrbaсhina细拉阿姆西震旦与食人魔实机兵种展示𝘳𝘦𝘢𝘭𝘭𝘺
00000000000...0000000000
10000000000...0000000000
20000000000...0000000000
30000000000...0000000000
40000001000...0000000000
\n", + "

5 rows × 10963 columns

\n", + "
" + ], + "text/plain": [ + " aaa aaron aau ab aba abandon abandoned abandoning abdel abducted \\\n", + "0 0 0 0 0 0 0 0 0 0 0 \n", + "1 0 0 0 0 0 0 0 0 0 0 \n", + "2 0 0 0 0 0 0 0 0 0 0 \n", + "3 0 0 0 0 0 0 0 0 0 0 \n", + "4 0 0 0 0 0 0 1 0 0 0 \n", + "\n", + " ... zydrunas álvaro ďays šarić štrba сhina 细拉 阿姆西 震旦与食人魔实机兵种展示 \\\n", + "0 ... 0 0 0 0 0 0 0 0 0 \n", + "1 ... 0 0 0 0 0 0 0 0 0 \n", + "2 ... 0 0 0 0 0 0 0 0 0 \n", + "3 ... 0 0 0 0 0 0 0 0 0 \n", + "4 ... 0 0 0 0 0 0 0 0 0 \n", + "\n", + " 𝘳𝘦𝘢𝘭𝘭𝘺 \n", + "0 0 \n", + "1 0 \n", + "2 0 \n", + "3 0 \n", + "4 0 \n", + "\n", + "[5 rows x 10963 columns]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "2716ded1", + "outputId": "7d540e0f-61d3-4616-f5bc-12a86306469a" + }, + "source": [ + "df.post.head()\n", + "\n", + "\n" + ], + "id": "2716ded1", + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "0 hey guy used play game called world war s b...\n", + "1 one try fell trough “ floor ” broken video gam...\n", + "2 appreciate good sound right game excellent...\n", + "3 hi m retired bored tear thing reading...\n", + "4 valve since usually good job private corporati...\n", + "Name: post, dtype: object" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "f8c4f82b" + }, + "source": [ + "#LDA" + ], + "id": "f8c4f82b", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "e9ce2288", + "outputId": "ccb05014-a35e-4f26-8301-4fcdd115fc46" + }, + "source": [ + "dictionary = Dictionary(df.token)\n", + "print('Number of unique words in initital documents:', len(dictionary))\n", + "\n", + "# Filter out words that occur less than 10 documents, or more than 20% of the documents.\n", + "dictionary.filter_extremes(no_below=10, no_above=0.2)\n", + "print('Number of unique words after removing rare and common words:', len(dictionary))" + ], + "id": "e9ce2288", + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of unique words in initital documents: 11096\n", + "Number of unique words after removing rare and common words: 1622\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8120f950" + }, + "source": [ + "corpus = [dictionary.doc2bow(doc) for doc in df.token]" + ], + "id": "8120f950", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "019c2b1a", + "outputId": "e5f0a9e9-e451-4742-ec85-64e3c8f06c39" + }, + "source": [ + "print('Number of unique tokens: %d' % len(dictionary))\n", + "print('Number of documents: %d' % len(corpus))" + ], + "id": "019c2b1a", + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of unique tokens: 1622\n", + "Number of documents: 1713\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "28274d12" + }, + "source": [ + "from gensim.models import LdaModel" + ], + "id": "28274d12", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "1b7cd03e", + "outputId": "e8867232-5076-493a-c1a1-1c2fe12f48ea" + }, + "source": [ + "# Set training parameters.\n", + "num_topics = 8\n", + "chunksize = 500 # size of the doc looked at every pass\n", + "passes = 20 # number of passes through documents\n", + "iterations = 400\n", + "eval_every = 1 # Don't evaluate model perplexity, takes too much time.\n", + "\n", + "# Make a index to word dictionary.\n", + "temp = dictionary[0] # This is only to \"load\" the dictionary.\n", + "id2word = dictionary.id2token\n", + "\n", + "%time model = LdaModel(corpus=corpus, id2word=id2word, chunksize=chunksize, \\\n", + " alpha='auto', eta='auto', \\\n", + " iterations=iterations, num_topics=num_topics, \\\n", + " passes=passes, eval_every=eval_every)" + ], + "id": "1b7cd03e", + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 22.6 s, sys: 50.3 ms, total: 22.6 s\n", + "Wall time: 22.7 s\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "35ee79f1" + }, + "source": [ + "" + ], + "id": "35ee79f1" + }, + { + "cell_type": "code", + "metadata": { + "id": "277cdbae" + }, + "source": [ + "import pyLDAvis.gensim\n", + "pyLDAvis.enable_notebook()\n", + "\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\", category=DeprecationWarning) " + ], + "id": "277cdbae", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "a16433ce", + "outputId": "9ea67fbb-ff7c-4098-bbac-5246121d606c" + }, + "source": [ + "pyLDAvis.gensim.prepare(model, corpus, dictionary)" + ], + "id": "a16433ce", + "execution_count": null, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/safarji/opt/anaconda3/lib/python3.8/site-packages/pyLDAvis/_prepare.py:247: FutureWarning: In a future version of pandas all arguments of DataFrame.drop except for the argument 'labels' will be keyword-only\n", + " default_term_info = default_term_info.sort_values(\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "
\n", + "" + ], + "text/plain": [ + "PreparedData(topic_coordinates= x y topics cluster Freq\n", + "topic \n", + "4 0.202521 -0.008545 1 1 30.404284\n", + "0 0.040647 -0.070906 2 1 13.993698\n", + "1 0.137097 -0.083399 3 1 13.749136\n", + "3 -0.173814 -0.005597 4 1 13.580189\n", + "7 -0.371680 -0.151542 5 1 12.408949\n", + "5 0.219281 -0.101934 6 1 11.140826\n", + "2 -0.055027 0.344820 7 1 3.614182\n", + "6 0.000975 0.077103 8 1 1.108736, topic_info= Term Freq Total Category logprob loglift\n", + "600 a 407.000000 407.000000 Default 30.0000 30.0000\n", + "1458 pf 351.000000 351.000000 Default 29.0000 29.0000\n", + "1323 basketball 503.000000 503.000000 Default 28.0000 28.0000\n", + "1269 ball 441.000000 441.000000 Default 27.0000 27.0000\n", + "1180 pt 308.000000 308.000000 Default 26.0000 26.0000\n", + "... ... ... ... ... ... ...\n", + "65 hand 12.240166 143.355685 Topic8 -4.1775 2.0413\n", + "381 use 8.232720 108.664837 Topic8 -4.5741 1.9218\n", + "144 since 9.177719 176.292631 Topic8 -4.4654 1.5466\n", + "240 give 7.907935 116.380474 Topic8 -4.6143 1.8130\n", + "1019 improve 6.028435 73.927049 Topic8 -4.8857 1.9954\n", + "\n", + "[447 rows x 6 columns], token_table= Topic Freq Term\n", + "term \n", + "600 1 0.004905 a\n", + "600 5 0.993242 a\n", + "1620 3 0.975390 aau\n", + "880 1 0.101456 account\n", + "880 6 0.879287 account\n", + "... ... ... ...\n", + "722 2 0.112750 youtube\n", + "722 3 0.225501 youtube\n", + "722 8 0.620127 youtube\n", + "48 3 0.991751 “\n", + "49 3 0.992941 ”\n", + "\n", + "[734 rows x 3 columns], R=30, lambda_step=0.01, plot_opts={'xlab': 'PC1', 'ylab': 'PC2'}, topic_order=[5, 1, 2, 4, 8, 6, 3, 7])" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d93a7dae" + }, + "source": [ + "" + ], + "id": "d93a7dae", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "02628e6a" + }, + "source": [ + "" + ], + "id": "02628e6a", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "2e20cf42" + }, + "source": [ + "#cv1.get_feature_names()[0:1000]" + ], + "id": "2e20cf42", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "45be0285" + }, + "source": [ + "" + ], + "id": "45be0285", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "d356b490" + }, + "source": [ + "" + ], + "id": "d356b490", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "666cdcd5" + }, + "source": [ + "" + ], + "id": "666cdcd5", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ef50ad8f" + }, + "source": [ + "### NMF" + ], + "id": "ef50ad8f" + }, + { + "cell_type": "code", + "metadata": { + "id": "66ba8581" + }, + "source": [ + "nmf_model = NMF(10)\n", + "doc_topic = nmf_model.fit_transform(c)" + ], + "id": "66ba8581", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "b7ae3edf", + "outputId": "b7f64d2d-03de-4e03-b6c9-90700abedc23" + }, + "source": [ + "topic_word = pd.DataFrame(nmf_model.components_.round(3),\n", + " index = [\"component_1\",\"component_2\",'component_3','component_4','component_5','component_6','component_7','component_8','component_9','component_10'],\n", + " columns = cv1.get_feature_names())\n", + "topic_word" + ], + "id": "b7ae3edf", + "execution_count": null, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
aaaaaronaauababaabandonabandonedabandoningabdelabducted...zydrunasálvaroďaysšarićštrbaсhina细拉阿姆西震旦与食人魔实机兵种展示𝘳𝘦𝘢𝘭𝘭𝘺
component_10.0030.0000.0000.0000.0000.0010.0000.0000.0000.000...0.0000.0030.0000.0000.0000.0000.0040.0000.0000.001
component_20.0000.0030.3130.0000.0010.0000.0000.0000.0000.000...0.0040.0010.0000.0040.0000.0020.0010.0000.0000.001
component_30.0040.0000.0000.0000.0000.0000.0000.0000.0000.000...0.0000.0000.0000.0000.0000.0010.0000.0000.0000.000
component_40.0950.0000.0000.0000.0000.0000.0000.0000.0000.000...0.0000.0890.0000.0000.0000.0000.0010.0000.0000.000
component_50.0000.3190.0000.0000.0010.0000.0000.0000.0470.000...0.0010.0000.0000.0000.0000.0010.0000.0010.0010.000
component_60.0030.0000.0000.0000.0000.0000.0000.0000.0000.000...0.0000.0010.0000.0000.0910.0000.0010.0000.0000.000
component_70.0240.0000.0020.0000.0000.0010.0000.0020.0000.082...0.0020.0010.0000.0010.0000.0000.0030.0000.0000.003
component_80.0050.0000.0000.0000.0000.0000.0000.0000.0000.000...0.0000.0000.0000.0000.0000.0000.0000.0000.0000.000
component_90.0010.0030.0000.0020.0040.0000.0010.0060.0000.000...0.0140.0000.0020.0050.0000.0030.0020.0000.0000.002
component_100.1070.0000.0000.0000.0000.0010.0000.0010.0000.000...0.0000.0010.0000.0000.0000.0000.0030.0000.0000.004
\n", + "

10 rows × 10963 columns

\n", + "
" + ], + "text/plain": [ + " aaa aaron aau ab aba abandon abandoned \\\n", + "component_1 0.003 0.000 0.000 0.000 0.000 0.001 0.000 \n", + "component_2 0.000 0.003 0.313 0.000 0.001 0.000 0.000 \n", + "component_3 0.004 0.000 0.000 0.000 0.000 0.000 0.000 \n", + "component_4 0.095 0.000 0.000 0.000 0.000 0.000 0.000 \n", + "component_5 0.000 0.319 0.000 0.000 0.001 0.000 0.000 \n", + "component_6 0.003 0.000 0.000 0.000 0.000 0.000 0.000 \n", + "component_7 0.024 0.000 0.002 0.000 0.000 0.001 0.000 \n", + "component_8 0.005 0.000 0.000 0.000 0.000 0.000 0.000 \n", + "component_9 0.001 0.003 0.000 0.002 0.004 0.000 0.001 \n", + "component_10 0.107 0.000 0.000 0.000 0.000 0.001 0.000 \n", + "\n", + " abandoning abdel abducted ... zydrunas álvaro ďays \\\n", + "component_1 0.000 0.000 0.000 ... 0.000 0.003 0.000 \n", + "component_2 0.000 0.000 0.000 ... 0.004 0.001 0.000 \n", + "component_3 0.000 0.000 0.000 ... 0.000 0.000 0.000 \n", + "component_4 0.000 0.000 0.000 ... 0.000 0.089 0.000 \n", + "component_5 0.000 0.047 0.000 ... 0.001 0.000 0.000 \n", + "component_6 0.000 0.000 0.000 ... 0.000 0.001 0.000 \n", + "component_7 0.002 0.000 0.082 ... 0.002 0.001 0.000 \n", + "component_8 0.000 0.000 0.000 ... 0.000 0.000 0.000 \n", + "component_9 0.006 0.000 0.000 ... 0.014 0.000 0.002 \n", + "component_10 0.001 0.000 0.000 ... 0.000 0.001 0.000 \n", + "\n", + " šarić štrba сhina 细拉 阿姆西 震旦与食人魔实机兵种展示 𝘳𝘦𝘢𝘭𝘭𝘺 \n", + "component_1 0.000 0.000 0.000 0.004 0.000 0.000 0.001 \n", + "component_2 0.004 0.000 0.002 0.001 0.000 0.000 0.001 \n", + "component_3 0.000 0.000 0.001 0.000 0.000 0.000 0.000 \n", + "component_4 0.000 0.000 0.000 0.001 0.000 0.000 0.000 \n", + "component_5 0.000 0.000 0.001 0.000 0.001 0.001 0.000 \n", + "component_6 0.000 0.091 0.000 0.001 0.000 0.000 0.000 \n", + "component_7 0.001 0.000 0.000 0.003 0.000 0.000 0.003 \n", + "component_8 0.000 0.000 0.000 0.000 0.000 0.000 0.000 \n", + "component_9 0.005 0.000 0.003 0.002 0.000 0.000 0.002 \n", + "component_10 0.000 0.000 0.000 0.003 0.000 0.000 0.004 \n", + "\n", + "[10 rows x 10963 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "c2918506" + }, + "source": [ + "def display_topics(model, feature_names, no_top_words, topic_names=None):\n", + " for ix, topic in enumerate(model.components_):\n", + " if not topic_names or not topic_names[ix]:\n", + " print(\"\\nTopic \", ix)\n", + " else:\n", + " print(\"\\nTopic: '\",topic_names[ix],\"'\")\n", + " print(\", \".join([feature_names[i]\n", + " for i in topic.argsort()[:-no_top_words - 1:-1]]))" + ], + "id": "c2918506", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "scrolled": false, + "id": "beeb9dd0", + "outputId": "79642d01-375b-4120-e2a4-a5273c9d5b85" + }, + "source": [ + "display_topics(nmf_model, cv1.get_feature_names(), 30)" + ], + "id": "beeb9dd0", + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Topic 0\n", + "horizon, game, forza, xsx, series, racing, best, world, open, pc, critic, xbox, new, one, mexico, star, experience, fun, entry, time, good, racer, motorsport, made, formula, content, everything, offer, fan, title\n", + "\n", + "Topic 1\n", + "team, player, nba, jvbl, league, year, school, new, contract, organization, system, basketball, may, ncaa, feeder, host, current, per, age, draft, season, deal, one, play, coach, idea, university, number, time, game\n", + "\n", + "Topic 2\n", + "world, game, banjo, character, one, duo, tooie, transformation, first, original, kazooie, mumbo, pad, fight, lot, flight, humba, take, section, better, fps, element, bos, ability, new, switch, moment, fun, different, peak\n", + "\n", + "Topic 3\n", + "tensei, megami, shin, game, nintendo, switch, combat, jrpg, one, series, fan, star, world, atlus, entry, time, trailer, new, gameplay, story, lot, rpg, best, great, worth, franchise, excellent, review, experience, even\n", + "\n", + "Topic 4\n", + "team, pf, pt, nba, ast, stl, blk, pm, com, min, game, fg, stats, ft, pg, sf, sg, reb, fgm, orb, drb, ftm, score, box, location, play, center, jr, total, clock\n", + "\n", + "Topic 5\n", + "party, mario, superstar, game, board, best, nintendo, minigames, new, series, fun, star, nostalgia, time, franchise, look, offer, perfect, selection, content, classic, first, year, feel, switch, super, review, great, back, fan\n", + "\n", + "Topic 6\n", + "game, resident, evil, outcome, player, demo, claim, ethan, information, release, time, village, leak, one, story, true, villain, character, major, chris, leaked, insider, year, seems, see, may, reveal, capcom, false, interesting\n", + "\n", + "Topic 7\n", + "second, dive, brigitte, hero, comp, character, ally, change, ability, counter, range, problem, damage, armor, inspire, pack, repair, team, enemy, health, enough, shield, overwatch, time, effective, meter, idea, something, need, player\n", + "\n", + "Topic 8\n", + "game, season, minute, year, play, basketball, good, time, player, even, ball, point, shot, really, issue, one, last, attempt, playing, best, got, know, shooting, defense, go, right, overwatch, guy, two, people\n", + "\n", + "Topic 9\n", + "game, rule, submission, link, thread, question, review, community, source, discussion, title, please, topic, republic, rider, may, video, crypto, indie, new, try, etc, platform, article, use, example, subreddit, following, specific, allowed\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e67d4ba9" + }, + "source": [ + "#df.to_csv('check1.csv')" + ], + "id": "e67d4ba9", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "89e8e1c4" + }, + "source": [ + "" + ], + "id": "89e8e1c4", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "raw", + "metadata": { + "id": "57f8d1c2" + }, + "source": [ + "" + ], + "id": "57f8d1c2" + }, + { + "cell_type": "markdown", + "metadata": { + "id": "c799c8a2" + }, + "source": [ + "coherence = []\n", + "for k in range(5,25):\n", + " print('Round: '+str(k))\n", + " Lda = gensim.models.ldamodel.LdaModel\n", + " ldamodel = Lda(doc_term_matrix, num_topics=k, \\\n", + " id2word = dict_, passes=40,\\\n", + " iterations=200, chunksize = 10000, eval_every = None)\n", + " \n", + " cm = gensim.models.coherencemodel.CoherenceModel(\\\n", + " model=ldamodel, texts=final_reviews,\\\n", + " dictionary=dict_, coherence='c_v') \n", + " \n", + " coherence.append((k,cm.get_coherence()))" + ], + "id": "c799c8a2" + }, + { + "cell_type": "code", + "metadata": { + "id": "5074b9d6", + "outputId": "36f5cae4-df22-4221-e204-cdb338efd5ba" + }, + "source": [ + "numberOfTopics=[]\n", + "explained_v=[]\n", + "for n_topics in range(1,20):\n", + " lsa = TruncatedSVD(n_topics)\n", + " doc_topic = lsa.fit_transform(c)\n", + " lsa.explained_variance_ratio_\n", + " numberOfTopics.append(len(lsa.explained_variance_ratio_))\n", + " explained_v.append(sum(lsa.explained_variance_ratio_))\n", + "plt.plot(numberOfTopics,explained_v)\n", + "plt.xlabel('number of topics')\n", + "plt.ylabel('explained variance ratio')" + ], + "id": "5074b9d6", + "execution_count": null, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0, 0.5, 'explained variance ratio')" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "fea07948" + }, + "source": [ + " lsa = TruncatedSVD(7)\n", + "doc_topic = lsa.fit_transform(c)\n" + ], + "id": "fea07948", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "43e47eb4", + "outputId": "4e52b679-1352-4043-e8af-eb7dba1e2871" + }, + "source": [ + "display_topics(lsa, cv1.get_feature_names(), 10)" + ], + "id": "43e47eb4", + "execution_count": null, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Topic 0\n", + "game, team, player, world, one, nba, new, time, year, horizon\n", + "\n", + "Topic 1\n", + "team, nba, player, jvbl, league, school, pf, pt, year, contract\n", + "\n", + "Topic 2\n", + "world, banjo, character, duo, tooie, transformation, original, mumbo, kazooie, first\n", + "\n", + "Topic 3\n", + "tensei, megami, shin, nintendo, party, switch, combat, jrpg, player, mario\n", + "\n", + "Topic 4\n", + "pf, pt, megami, tensei, shin, ast, stl, blk, pm, com\n", + "\n", + "Topic 5\n", + "party, mario, superstar, board, minigames, nintendo, nostalgia, pf, new, pt\n", + "\n", + "Topic 6\n", + "game, second, dive, rule, overwatch, brigitte, hero, submission, information, shot\n" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "e5f0d1ac" + }, + "source": [ + "df['token']=df.post.map(word_tokenize)" + ], + "id": "e5f0d1ac", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "763a1b10" + }, + "source": [ + "texts = df['token']\n", + "dictionary = Dictionary(texts)\n", + "dictionary.filter_extremes( no_below=3 ,no_above=0.85 ,keep_n=5000 )\n", + "corpus = [dictionary.doc2bow(text) for text in texts]\n", + "topic_nums = list(np.arange(5, 50, 5))" + ], + "id": "763a1b10", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "849373bc", + "outputId": "dd8c74ec-4267-4022-8617-3c225207e163" + }, + "source": [ + "coherence_scores = []\n", + "for num in topic_nums:\n", + " nmf = Nmf(\n", + " corpus=corpus,\n", + " num_topics=num,\n", + " id2word=dictionary,\n", + " chunksize=2000,\n", + " passes=5,\n", + " kappa=.1,\n", + " minimum_probability=0.01,\n", + " w_max_iter=300,\n", + " w_stop_condition=0.0001,\n", + " h_max_iter=100,\n", + " h_stop_condition=0.001,\n", + " eval_every=10,\n", + " normalize=True,\n", + " random_state=42\n", + " )\n", + " \n", + " # Run the coherence model to get the score\n", + " cm = CoherenceModel(\n", + " model=nmf,\n", + " texts=texts,\n", + " dictionary=dictionary,\n", + " coherence='c_v'\n", + " )\n", + " \n", + " coherence_scores.append(round(cm.get_coherence(), 5))\n", + "\n", + "# plot number of topics Vs coherence_scores\n", + "plt.plot(topic_nums,coherence_scores)\n", + "plt.xticks(topic_nums);\n", + "plt.xlabel('number of topics')\n", + "plt.ylabel('coherence score')" + ], + "id": "849373bc", + "execution_count": null, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'Nmf' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mcoherence_scores\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mnum\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtopic_nums\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m nmf = Nmf(\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mcorpus\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcorpus\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mnum_topics\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnum\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'Nmf' is not defined" + ] + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "8d594519" + }, + "source": [ + "\n", + "coherence_scores" + ], + "id": "8d594519", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "c00b698c" + }, + "source": [ + "topic_nums" + ], + "id": "c00b698c", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "133f9eab" + }, + "source": [ + "plt.plot(topic_nums,coherence_scores)\n", + "plt.xticks(topic_nums);" + ], + "id": "133f9eab", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f2d691b8" + }, + "source": [ + "#topic_word.to_csv('word_weight.csv')" + ], + "id": "f2d691b8", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "50234f2c", + "outputId": "f7b1238e-914a-45a6-8ea4-82f3fd8916df" + }, + "source": [ + "##ploting word weight for each topic\n", + "df1=topic_word.T\n", + "names=[]\n", + "for i in range(1,11):\n", + " name='topic'+str(i)\n", + " names.append(name)\n", + " \n", + "df1.columns=names\n", + "df1=df1.iloc[1:]\n", + "df1" + ], + "id": "50234f2c", + "execution_count": null, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
topic1topic2topic3topic4topic5topic6topic7topic8topic9topic10
aaron0.0000.0030.0000.0000.3190.0000.0000.00.0030.000
aau0.0000.3130.0000.0000.0000.0000.0020.00.0000.000
ab0.0000.0000.0000.0000.0000.0000.0000.00.0020.000
aba0.0000.0010.0000.0000.0010.0000.0000.00.0040.000
abandon0.0010.0000.0000.0000.0000.0000.0010.00.0000.001
.................................
сhina0.0000.0020.0010.0000.0010.0000.0000.00.0030.000
细拉0.0040.0010.0000.0010.0000.0010.0030.00.0020.003
阿姆西0.0000.0000.0000.0000.0010.0000.0000.00.0000.000
震旦与食人魔实机兵种展示0.0000.0000.0000.0000.0010.0000.0000.00.0000.000
𝘳𝘦𝘢𝘭𝘭𝘺0.0010.0010.0000.0000.0000.0000.0030.00.0020.004
\n", + "

10962 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " topic1 topic2 topic3 topic4 topic5 topic6 topic7 topic8 \\\n", + "aaron 0.000 0.003 0.000 0.000 0.319 0.000 0.000 0.0 \n", + "aau 0.000 0.313 0.000 0.000 0.000 0.000 0.002 0.0 \n", + "ab 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.0 \n", + "aba 0.000 0.001 0.000 0.000 0.001 0.000 0.000 0.0 \n", + "abandon 0.001 0.000 0.000 0.000 0.000 0.000 0.001 0.0 \n", + "... ... ... ... ... ... ... ... ... \n", + "сhina 0.000 0.002 0.001 0.000 0.001 0.000 0.000 0.0 \n", + "细拉 0.004 0.001 0.000 0.001 0.000 0.001 0.003 0.0 \n", + "阿姆西 0.000 0.000 0.000 0.000 0.001 0.000 0.000 0.0 \n", + "震旦与食人魔实机兵种展示 0.000 0.000 0.000 0.000 0.001 0.000 0.000 0.0 \n", + "𝘳𝘦𝘢𝘭𝘭𝘺 0.001 0.001 0.000 0.000 0.000 0.000 0.003 0.0 \n", + "\n", + " topic9 topic10 \n", + "aaron 0.003 0.000 \n", + "aau 0.000 0.000 \n", + "ab 0.002 0.000 \n", + "aba 0.004 0.000 \n", + "abandon 0.000 0.001 \n", + "... ... ... \n", + "сhina 0.003 0.000 \n", + "细拉 0.002 0.003 \n", + "阿姆西 0.000 0.000 \n", + "震旦与食人魔实机兵种展示 0.000 0.000 \n", + "𝘳𝘦𝘢𝘭𝘭𝘺 0.002 0.004 \n", + "\n", + "[10962 rows x 10 columns]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "scrolled": false, + "id": "a0eb0a5f", + "outputId": "f797c1c2-a101-4181-bd41-e874c9ec3d7d" + }, + "source": [ + "for col in df1.columns:\n", + " temp=df1.sort_values(by=col,ascending=False).iloc[0:5]\n", + " plt.figure()\n", + " sns.barplot(data=temp,y=temp.index,x=temp[col],palette=\"crest\")\n", + " plt.xticks([])\n", + " plt.xlabel('Word weight ')\n", + " plt.title(col);\n", + " " + ], + "id": "a0eb0a5f", + "execution_count": null, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAEFCAYAAAAIZiutAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAARyUlEQVR4nO3deZBdZZ3G8e+jAjGGRQXRAKGVRWQTJaBIVBwYxFEsdwaRMSpmcCgVF3RGQQfRwnUclRklKmK5b8gIqMggCoRFEhBCEMSFGAyiqICAoJDf/HFPaq79dpIO3TedpL+fqq577vu+5z2/k6r00+85d0lVIUlSvwdMdAGSpLWP4SBJahgOkqSG4SBJahgOkqSG4SBJahgO0hqQ5KlJrpvoOqTRMhyklUhyQ5IDxjpPVV1QVY8dxfGS5O1JfpXk9iRfTrLJWI8vrS7DQVq7/BNwOLAvMB14MPCxCa1Ik5LhIK1Aks8BM4AzktyR5C1JnptkUZJbk/wgyeP6xt+Q5N+SXJPkj0k+k2RK17dfkhv7xm6T5LQkv0vy+yQndV0HA5+uqiVVdQfwPuCQJFPX3JlLhoO0QlV1OPAr4OCqmgacDnwJOBrYAvg2veDYsG+3w4BnAtsBOwLHDp83yQOBM4HFwBCwFfDl5d3dD33PNwJ2GJ+zkkbHcJBG7xDgrKo6p6r+CnyQ3mWfp/SNOan7q/8PwHuAQ0eYZ296l4yOqao7q+ruqrqw6/sOcESSoSSbAm/t2l05aI0yHKTRm07vr30AqmoZsITeX/7LLenbXtztM9w2wOKquneEvlPorU5+ACwCzuvabxxhrDQwhoO0cv0fW7wU2Hb5kySh94v+131jtunbntHtM9wSYEaSBzUHq1pWVe+sqqGq2ppeQPx62DGkgTMcpJW7GXhMt/1V4NlJ9k+yAfAm4B7gor7xRyXZOsnDgLcBXxlhzh8BNwHvTfKQJFOS7AuQ5GFJtute0roz8B/Au7pVirTGGA7Syp0IHJvkVnqvJHoZvZeW3tI9P7iq/tI3/ovA94BfdD/vHj5hVd3X7bs9vRveN9K7nwGwOb0b3XfSu/9wSlXNHfezklYhftmPND6S3AAcUVX/O9G1SGPlykGS1DAcJEkNLytJkhquHCRJjeZ11uuizTffvIaGhia6DElapyxYsOCWqtpipL71IhyGhoaYP3/+RJchSeuUJItX1OdlJUlSw3CQJDUMB0lSY72457D01t/yztP9sixJk8vxz3vtwOZ25SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJaoz5+xySHAccBiwBbgEWALcBc4ANgZ8Bh1fVXUlOBf4M7ARsC7wCeDmwD3BpVc3u5jwQOB7YCPg58IqqumOstUqSRmdMK4ckM4EXAk8AXgDM7LpOq6q9qurxwE+AV/Xt9lDg74A3AGcAHwZ2AXZLskeSzYFjgQOq6onAfOCNIxx7TpL5Sebfdbu5IUnjaawrh1nA/1TVnwGSnNG175rk3cBmwDTg7L59zqiqSrIQuLmqFnb7LgKGgK2BnYF5SaC3+rh4+IGrai4wF2D69jNqjOchSeoz1nDICtpPBZ5XVVcmmQ3s19d3T/e4rG97+fMHAfcB51TVoWOsTZJ0P431hvSFwMFJpiSZBjy7a98YuCnJBvTuR6yOS4B9k2wPkGRqkh3HWKckaTWMaeVQVZcl+RZwJbCY3v2B24DjgEu7toX0wmK0c/6uW218KclGXfOxwE/HUqskafTG/Gol4INV9e9JpgLnAx+qqsuBjw8fuPzVSN32DcCuK+j7PrDXONQmSbofxiMc5ibZGZgCfLYLBknSOmzM4VBVLx2PQiRJaw/fIS1JahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJahgOkqSG4SBJaozHx2dMuOmbPYLjn/faiS5DktYbrhwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUWC/eBPfL3/6Gw/7rAxNdhiTxhaOOmegSxoUrB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSY5XhkOQhSc5KcmWSq5MckmTPJD9MsiDJ2Uke1Y19dZLLurHfSDK1a39xt++VSc7v2qYk+UyShUmuSPKMrn12ktOSfDfJ9UneP8h/AElSazQrh4OApVX1+KraFfgu8DHgRVW1J3AK8J5u7GlVtVdVPR74CfCqrv0dwDO79ud2bUcBVNVuwKHAZ5NM6fr2AA4BdgMOSbLNGM5RkrSaRvNNcAuBDyZ5H3Am8EdgV+CcJAAPBG7qxu6a5N3AZsA04OyufR5wapKvAqd1bbPohQxVdW2SxcCOXd+5VXUbQJJrgG2BJf1FJZkDzAGY+tDNRn3CkqRVW2U4VNVPk+wJ/ANwInAOsKiq9hlh+KnA86rqyiSzgf26OY5M8iTg2cCPk+wBZCWHvadv+76R6qyqucBcgIfP2LpWdR6SpNEbzT2H6cBdVfV54IPAk4AtkuzT9W+QZJdu+MbATUk2AA7rm2O7qrq0qt4B3AJsA5y/fEySHYEZwHXjdmaSpPttNJeVdgM+kGQZ8FfgNcC9wEeTbNrN8Z/AIuA44FJgMb3LURt3c3wgyQ70VgvnAlcC1wKfSLKwm292Vd3TXaqSJE2gVK37V2QePmPrOuitr5/oMiSJLxx1zESXMGpJFlTVzJH6fJ+DJKlhOEiSGoaDJKlhOEiSGoaDJKlhOEiSGoaDJKlhOEiSGoaDJKlhOEiSGoaDJKlhOEiSGqP5VNa13qMf8ch16sOuJGlt58pBktQwHCRJDcNBktQwHCRJDcNBktQwHCRJDcNBktQwHCRJjfXiTXDXLb2Jpx93wkSXIWmS+uEJx010CePOlYMkqWE4SJIahoMkqWE4SJIahoMkqWE4SJIahoMkqWE4SJIahoMkqWE4SJIahoMkqWE4SJIahoMkqTEu4ZDkuUn+dQz7H51k6njUIkkau3EJh6r6VlW9dwxTHA0YDpK0llhlOCQZSnJtkk8luTrJF5IckGRekuuT7J1kdpKTuvGnJvlokouS/CLJi7r2/ZKc2TfvSd1+rwOmA+clOa/rOzDJxUkuT/K1JNMGc/qSpJGMduWwPfARYHdgJ+ClwCzgzcDbRhj/qK7/OcBKVxRV9VFgKfCMqnpGks2BY4EDquqJwHzgjcP3SzInyfwk8/96552jPA1J0miM9pvgfllVCwGSLALOrapKshAYGmH86VW1DLgmyZarWdOTgZ2BeUkANgQuHj6oquYCcwE2nr5VreYxJEkrMdpwuKdve1nf82UrmKN/fLrHe/nblcqUFRwrwDlVdegoa5MkjbM1+VLWxcDOSTZKsimwf1/fn4CNu+1LgH2TbA+QZGqSHddgnZI06Y125TBmVbUkyVeBq4DrgSv6uucC30lyU3ffYTbwpSQbdf3HAj9dU7VK0mSXqnX/cv3G07eqJ77qyIkuQ9Ik9cMTjpvoEu6XJAuqauZIfb5DWpLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUWGMfvDdIj53+qHX2s00kaW3kykGS1DAcJEkNw0GS1DAcJEkNw0GS1DAcJEkNw0GS1DAcJEmN9eJNcIsWL2XXf/ZNcJIG4+qTT5joEtY4Vw6SpIbhIElqGA6SpIbhIElqGA6SpIbhIElqGA6SpIbhIElqGA6SpIbhIElqGA6SpIbhIElqGA6SpIbhIElqrBPhkOSBE12DJE0m4x4OSU5I8vq+5+9J8rokxyS5LMlVSY7v6z89yYIki5LM6Wu/I8m7klwK7DPedUqSVmwQK4dPAy8HSPIA4B+Bm4EdgL2BPYA9kzytG//KqtoTmAm8LsnDu/aHAFdX1ZOq6sIB1ClJWoFx/ya4qrohye+TPAHYErgC2As4sNsGmEYvLM6nFwjP79q36dp/D9wHfGNFx+lWGXMANpi2yXifhiRNaoP6mtBPAbOBRwKnAPsDJ1bVyf2DkuwHHADsU1V3JfkBMKXrvruq7lvRAapqLjAX4MFbTK/xLV+SJrdB3ZD+JnAQvRXD2d3PK5NMA0iyVZJHAJsCf+yCYSfgyQOqR5K0GgaycqiqvyQ5D7i1++v/e0keB1ycBOAO4GXAd4Ejk1wFXAdcMoh6JEmrZyDh0N2IfjLw4uVtVfUR4CMjDH/WSHNU1bRB1CZJWrVBvJR1Z+BnwLlVdf14zy9JGrxBvFrpGuAx4z2vJGnNWSfeIS1JWrMMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSY1Df57BG7bLtdOaffMJElyFJ6w1XDpKkhuEgSWoYDpKkhuEgSWoYDpKkhuEgSWoYDpKkhuEgSWqsF2+Cu+bnN7LH898y0WVImkA//ub7J7qE9YorB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSw3CQJDUMB0lSY42HQ5IfJJm5po8rSRo9Vw6SpMbAwiHJUJJrk3w2yVVJvp5k6rAxH08yP8miJMd3bfsn+WbfmL9Pctqg6pQktQa9cngsMLeqdgduB/5lWP/bq2omsDvw9CS7A98HHpdki27MK4DPDJ84yZwuWObfe8+fB3cGkjQJDTocllTVvG7788CsYf0vSXI5cAWwC7BzVRXwOeBlSTYD9gG+M3ziqppbVTOrauaDNnrwwE5AkiajQX9NaK3oeZJHA28G9qqqPyY5FZjSdX8GOAO4G/haVd074DolSX0GvXKYkWSfbvtQ4MK+vk2AO4HbkmwJPGt5R1UtBZYCxwKnDrhGSdIwgw6HnwAvT3IV8DDg48s7qupKepeTFgGnAPOG7fsFepelrhlwjZKkYQZ9WWlZVR05rG2/5RtVNXsl+84CPjmAmiRJqzDocLhfkiygd8npTRNdiyRNRgMLh6q6Adj1fu675/hWI0laHb5DWpLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUMBwkSQ3DQZLUWCs/PmN17bzd1sz/5vsnugxJWm+4cpAkNQwHSVLDcJAkNQwHSVIjVcO/5nndk+R3wOKJrkOS1jHbVtUWI3WsF+EgSRpfXlaSJDUMB0lSw3CQJDUMB63Xknw4ydF9z89O8qm+5x9K8sb7Ofd+Sc4chzL757xoFGNuSLL5Cup5ynjWo8nLcND67iLgKQBJHgBsDuzS1/8UYN5oJkrywHGvbpiqGssv9/3ozlUaK8NB67t5/P8vzF2Aq4E/JXloko2AxwFXJNk/yRVJFiY5petb/lf6O5JcCLw4yUFJru2ev2CkAyb5dpLdu+0rkryj2z4hyRHd9jFJLktyVZLj+/a9o3t8QJL/TrIoyZndnC/qO8xrk1ze1btTkiHgSOANSX6c5Knj9Q+oyclw0HqtqpYC9yaZQS8kLgYuBfYBZgJX0ft/cCpwSFXtRu8DKV/TN83dVTULOB34JHAw8FTgkSs47PnAU5NsAtwL7Nu1zwIuSHIgsAOwN7AHsGeSpw2b4wXAELAbcERXb79bquqJwMeBN1fVDcAngA9X1R5VdcEq/mmklTIcNBksXz0sD4eL+55fBDwW+GVV/bQb/1mg/5f1V7rHnbpx11fvDUKfX8HxLuj2nwWcBUxLMhUYqqrrgAO7nyuAy7t5dxg2xyzga1W1rKp+A5w3rP+07nEBvRCRxtV68ZHd0iosv++wG73LSkuANwG3A6cAWcX+d/Ztj+Zdo5fRW5X8AjiH3n2OV9P7RU53vBOr6uSVzLGqmu7pHu/D/8caAFcOmgzmAc8B/lBV91XVH4DN6F2quRi4FhhKsn03/nDghyPMcy3w6CTbdc8PHelgVfUXegH0EuASeiuJN3ePAGcDr0wyDSDJVkkeMWyaC4EXdvcetqR3s3lV/gRsPIpx0ioZDpoMFtL76/2SYW23VdUtVXU38Arga0kWAsvoXb//G924OcBZ3Q3plX2e1wXAzVV1V7e9dfdIVX0P+CJwcXe8r9P+Uv8GcCO9lc7J9O6T3LaK8zwDeL43pDUe/GwlaS2VZFpV3ZHk4cCPgH27+w/SwHmtUlp7nZlkM2BD4ASDQWuSKwdJUsN7DpKkhuEgSWoYDpKkhuEgSWoYDpKkxv8B028xOMAZxKMAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "b784b01c" + }, + "source": [ + "" + ], + "id": "b784b01c", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "3cba23ca" + }, + "source": [ + "" + ], + "id": "3cba23ca", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "f9e01166" + }, + "source": [ + "" + ], + "id": "f9e01166", + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "87259e8e" + }, + "source": [ + "" + ], + "id": "87259e8e", + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file