Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@prb112
Last active November 23, 2020 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prb112/3a4541d9c4c6351d9064857ce2b1b442 to your computer and use it in GitHub Desktop.
Save prb112/3a4541d9c4c6351d9064857ce2b1b442 to your computer and use it in GitHub Desktop.
This demo shows how to use the IBM FHIR Server Docker image along with the IBM FHIR Server examples and `near` search parameter.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Using the IBM FHIR Server Location Search in Jupyter\n",
"\n",
"**Author**: [Paul Bastide](mailto:pbastide@us.ibm.com)\n",
"\n",
"The IBM FHIR Server supports FHIR Search with the SearchParameter `near` on the Location API. \n",
"\n",
"This notebook shows how to use the IBM FHIR Server examples with Location Search and use folium to render their plots.\n",
"\n",
"More advanced demonstrations can be generated from this location data which reference these Locations, and are retrieved using [FHIR Search - Reference](https://www.hl7.org/fhir/search.html#reference)."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All imports complete\n"
]
}
],
"source": [
"# The following imports are used in the analysis of the location data:\n",
"\n",
"# imported to retrieve any secondary data\n",
"import requests\n",
"\n",
"# import pandas to process the data (and json_normalize to use the geojson as a plain dataframe)\n",
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"# Import to control the output of the choropleth map\n",
"import matplotlib.cm as cm\n",
"import matplotlib.colors as colors\n",
"\n",
"# standard matplot lib \n",
"import matplotlib\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib.pyplot import figure\n",
"import matplotlib.dates as mdates\n",
"\n",
"# Import Folium to visualize the map\n",
"import folium\n",
"from folium import plugins\n",
"from folium.plugins import HeatMap\n",
"from folium.plugins import MarkerCluster\n",
"\n",
"# figures out the neighborhoods for each coordinate. \n",
"from shapely.geometry import Point \n",
"#(switched to geojson point to more precisely identify location)\n",
"#from geojson import Point\n",
"\n",
"# Imports the Clustering Utilities\n",
"from sklearn.cluster import DBSCAN\n",
"from sklearn import metrics\n",
"from sklearn.datasets.samples_generator import make_blobs\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.cluster import KMeans\n",
"\n",
"import json\n",
"from pandas.io.json import json_normalize\n",
"\n",
"# used to process fhir-examples\n",
"import zipfile, io\n",
"import urllib3\n",
"\n",
"print(\"All imports complete\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Download the fhir-examples\n",
"The following downloads the fhir-examples module."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# The URl for the most recent fhir-examples module.\n",
"fhir_examples_jar_url='https://dl.bintray.com/ibm-watson-health/ibm-fhir-server-releases/com/ibm/fhir/fhir-examples/4.5.0/fhir-examples-4.5.0.jar'\n",
"\n",
"r = requests.get(fhir_examples_jar_url)\n",
"z = zipfile.ZipFile(io.BytesIO(r.content))"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"# Authenticate\n",
"from requests.auth import HTTPBasicAuth\n",
"httpAuth = HTTPBasicAuth('fhiruser', 'change-password')\n",
"\n",
"# Get the Location using Requests\n",
"headers = {\n",
" 'Content-Type': 'application/json'\n",
"}\n",
"\n",
"# We choose to disable warnings, in production, please don't\n",
"urllib3.disable_warnings()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done uploading - json/ibm/bulk-data/location/\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-103.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-104.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-31.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-37.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-43.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-44.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-8.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-118.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-95.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-99.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-85.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-63.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-113.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-34.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-97.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-11.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-32.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-1.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-101.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-53.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-93.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-98.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-119.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-114.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-23.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-115.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-128.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-15.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-72.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-38.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-91.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-5.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-88.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-4.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-124.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-52.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-9.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-83.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-57.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-127.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-6.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-47.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-14.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-2.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-55.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-16.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-100.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-106.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-108.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-86.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-120.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-109.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-90.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-12.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-24.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-54.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-46.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-70.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-22.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-10.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-17.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-78.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-110.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-116.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-40.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-19.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-20.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-45.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-58.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-69.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-42.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-48.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-81.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-60.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-51.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-68.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-123.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-64.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-92.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-36.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-33.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-107.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-29.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-80.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-71.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-76.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-65.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-49.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-7.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-74.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-82.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-94.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-84.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-121.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-26.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-96.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-126.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-122.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-61.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-125.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-66.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-112.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-77.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-117.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-13.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-35.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-56.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-18.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-79.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-30.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-87.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-50.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-39.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-111.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-102.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-21.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-25.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-3.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-105.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-73.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-28.json\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-59.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-27.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-75.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-41.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-67.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-62.json\n",
"Done uploading - json/ibm/bulk-data/location/synthetic-mass-89.json\n"
]
}
],
"source": [
"# At this point we have z as a zip file and we can selectively process the zip file. \n",
"# this is kind of cool as we can go ahead and send these files right to the IBM FHIR Server. \n",
"entries = z.namelist()\n",
"for entry in entries: \n",
" if entry.startswith('json/ibm/bulk-data/location/'):\n",
" f = z.open(entry);\n",
" content = f.read()\n",
" r = requests.post('https://localhost:9443/fhir-server/api/v4/Location', \n",
" data=content,\n",
" headers=headers, \n",
" auth=httpAuth,\n",
" verify=False)\n",
" print('Done uploading - ' + entry)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Query the IBM FHIR Server with near"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"# Authenticate\n",
"from requests.auth import HTTPBasicAuth\n",
"httpAuth = HTTPBasicAuth('fhiruser', 'change-password')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"# Get the Location using Requests\n",
"headers = {\n",
" 'Content-Type': 'application/json'\n",
"}\n",
"\n",
"# Search within 10Km of Cambridge Massachusetts\n",
"queryParams = {\n",
" 'near': '42.373611|-71.110558|10|km',\n",
" \"_count\" : 200\n",
"}\n",
"\n",
"# Search Parameter = near=\n",
"resp_loc = requests.get('https://localhost:9443/fhir-server/api/v4/Location', \n",
" headers=headers, \n",
" params=queryParams,\n",
" auth=httpAuth,\n",
" verify=False)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"# Convert to a list\n",
"response_loc_json = json.loads(resp_loc.text)\n",
"\n",
"location_rows = []\n",
"for location in response_loc_json['entry']:\n",
" row = pd.json_normalize(location)\n",
" lat_inc = float(row['resource.position.latitude'])\n",
" location_rows.append(row)\n",
" \n",
"# If you are debugging... print(rows_list)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Found this number of Locations: 44\n"
]
}
],
"source": [
"print('Found this number of Locations: ' + str(len(location_rows)))"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgPHN0eWxlPiNtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQgewogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICB3aWR0aDogMTAwLjAlOwogICAgICAgIGhlaWdodDogMTAwLjAlOwogICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgdG9wOiAwLjAlOwogICAgICAgIH0KICAgIDwvc3R5bGU+CjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0IiA+PC9kaXY+CjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKICAgIAogICAgICAgIHZhciBib3VuZHMgPSBudWxsOwogICAgCgogICAgdmFyIG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCA9IEwubWFwKAogICAgICAgICdtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQnLCB7CiAgICAgICAgY2VudGVyOiBbNDIuMzczNjExLCAtNzEuMTFdLAogICAgICAgIHpvb206IDEwLAogICAgICAgIG1heEJvdW5kczogYm91bmRzLAogICAgICAgIGxheWVyczogW10sCiAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICB9KTsKCiAgICAKICAgIAogICAgdmFyIHRpbGVfbGF5ZXJfMDI0OWEwZTczMGFkNGQ4ZDk3ZDU1YzY2MmU0Y2UzYjkgPSBMLnRpbGVMYXllcigKICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgIHsKICAgICAgICAiYXR0cmlidXRpb24iOiBudWxsLAogICAgICAgICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAgICAgICAibWF4TmF0aXZlWm9vbSI6IDE4LAogICAgICAgICJtYXhab29tIjogMTgsCiAgICAgICAgIm1pblpvb20iOiAwLAogICAgICAgICJub1dyYXAiOiBmYWxzZSwKICAgICAgICAic3ViZG9tYWlucyI6ICJhYmMiCn0pLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjM4MzU0NmI0ZjZhNDE4M2E0YWFmZTQwNzAzMjI3OGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zMjY5OCwgLTcxLjExMDYzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mMzMyYTY2NGFmMjk0MDA0YWEyOTA2NWUwNjI5YTM5OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUxZGI2NWMzOTVjMTRiNmRhM2VlMTcxODFhNWZkMWU4ID0gJCgnPGRpdiBpZD0iaHRtbF81MWRiNjVjMzk1YzE0YjZkYTNlZTE3MTgxYTVmZDFlOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gNDQgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjMzMmE2NjRhZjI5NDAwNGFhMjkwNjVlMDYyOWEzOTguc2V0Q29udGVudChodG1sXzUxZGI2NWMzOTVjMTRiNmRhM2VlMTcxODFhNWZkMWU4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzYzODM1NDZiNGY2YTQxODNhNGFhZmU0MDcwMzIyNzhkLmJpbmRQb3B1cChwb3B1cF9mMzMyYTY2NGFmMjk0MDA0YWEyOTA2NWUwNjI5YTM5OCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWQ4MGM5ZDcwMjFiNDA0OTg4NDcwYzIzMjhiNjllY2MgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi40MjYyOSwgLTcxLjExMTFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2QyZmZjMWEwZmYxODQ0YzBhOTI3ZGUzZmU4MzgyMzA2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2U3NTdhZjdmODIyNDdkYThjN2ZkNzk1OGZhY2U1MzQgPSAkKCc8ZGl2IGlkPSJodG1sX2NlNzU3YWY3ZjgyMjQ3ZGE4YzdmZDc5NThmYWNlNTM0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA4IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QyZmZjMWEwZmYxODQ0YzBhOTI3ZGUzZmU4MzgyMzA2LnNldENvbnRlbnQoaHRtbF9jZTc1N2FmN2Y4MjI0N2RhOGM3ZmQ3OTU4ZmFjZTUzNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xZDgwYzlkNzAyMWI0MDQ5ODg0NzBjMjMyOGI2OWVjYy5iaW5kUG9wdXAocG9wdXBfZDJmZmMxYTBmZjE4NDRjMGE5MjdkZTNmZTgzODIzMDYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YzZjczZmI2MWViYjQ3ZmQ5NTUwNTk4ZGI5N2U3ODZlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzUwMzUsIC03MS4wNjM3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODFjNmJiZWY2ZTc1NGI5ZmJiODUyZmY0OTZiNDU0YTggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yOTQxYTEzMThhZmI0MDk0YWE3ODU4ZTk3ZDUzZjk1OSA9ICQoJzxkaXYgaWQ9Imh0bWxfMjk0MWExMzE4YWZiNDA5NGFhNzg1OGU5N2Q1M2Y5NTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDk5IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzgxYzZiYmVmNmU3NTRiOWZiYjg1MmZmNDk2YjQ1NGE4LnNldENvbnRlbnQoaHRtbF8yOTQxYTEzMThhZmI0MDk0YWE3ODU4ZTk3ZDUzZjk1OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mM2Y3M2ZiNjFlYmI0N2ZkOTU1MDU5OGRiOTdlNzg2ZS5iaW5kUG9wdXAocG9wdXBfODFjNmJiZWY2ZTc1NGI5ZmJiODUyZmY0OTZiNDU0YTgpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzkyNjkyNjMwM2MwNjQwZWViMmY5ZGM0MTZkNmY2ZWJkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzk2MTQsIC03MS4wMzkxNF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOWQwYWM4MTA5NjQ5NGE0MmIwYTgxZTNjZTk4YTU5YTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jYzY4M2M2MjdlMTE0MDhlOTU2ZmQ5YjRiZGY5NTIyYyA9ICQoJzxkaXYgaWQ9Imh0bWxfY2M2ODNjNjI3ZTExNDA4ZTk1NmZkOWI0YmRmOTUyMmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDM0IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzlkMGFjODEwOTY0OTRhNDJiMGE4MWUzY2U5OGE1OWE5LnNldENvbnRlbnQoaHRtbF9jYzY4M2M2MjdlMTE0MDhlOTU2ZmQ5YjRiZGY5NTIyYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85MjY5MjYzMDNjMDY0MGVlYjJmOWRjNDE2ZDZmNmViZC5iaW5kUG9wdXAocG9wdXBfOWQwYWM4MTA5NjQ5NGE0MmIwYTgxZTNjZTk4YTU5YTkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzZhNzcyYWI0MTQ2NTRlZjA4OGI3Mjc2NGUxZmEzNmFiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzYyNzMsIC03MS4wNzAxMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzA0NmU2MGM1ZWM1NGI0NTliMjc3NDlhZDYxMGFjYTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNjExYWZlMDMxNmY0YmFmOGFiMDBhY2U0NjFkNjNmMSA9ICQoJzxkaXYgaWQ9Imh0bWxfZjYxMWFmZTAzMTZmNGJhZjhhYjAwYWNlNDYxZDYzZjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDExNCBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MDQ2ZTYwYzVlYzU0YjQ1OWIyNzc0OWFkNjEwYWNhNC5zZXRDb250ZW50KGh0bWxfZjYxMWFmZTAzMTZmNGJhZjhhYjAwYWNlNDYxZDYzZjEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNmE3NzJhYjQxNDY1NGVmMDg4YjcyNzY0ZTFmYTM2YWIuYmluZFBvcHVwKHBvcHVwXzcwNDZlNjBjNWVjNTRiNDU5YjI3NzQ5YWQ2MTBhY2E0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84ZjkxYzRlYTlmNDI0M2I0YjQ4MDVkMWVlNjc4NDczNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjM1MDU0LCAtNzEuMDc2NzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFjNmEzNDE5NjRjZDRkMDRhMWIxZjZiYTFjODU1MjIwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGJiMzVkMDczNTZhNDg3MjlhZjA4M2ZiMjJmODNkNmEgPSAkKCc8ZGl2IGlkPSJodG1sX2RiYjM1ZDA3MzU2YTQ4NzI5YWYwODNmYjIyZjgzZDZhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSAyMyBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xYzZhMzQxOTY0Y2Q0ZDA0YTFiMWY2YmExYzg1NTIyMC5zZXRDb250ZW50KGh0bWxfZGJiMzVkMDczNTZhNDg3MjlhZjA4M2ZiMjJmODNkNmEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOGY5MWM0ZWE5ZjQyNDNiNGI0ODA1ZDFlZTY3ODQ3MzUuYmluZFBvcHVwKHBvcHVwXzFjNmEzNDE5NjRjZDRkMDRhMWIxZjZiYTFjODU1MjIwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hYTY1MzgxNDA0Zjc0NTdhOTE2ZDZhZmE4NTIwMThkYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMwMTY0LCAtNzEuMTI4NzhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhkNmQyMzc5MGVlMzQ3Mzk5MjkzMWI4YzdhZmUyOTJlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMThiNjEzZDc5YTI3NGMxNzg1ODliNDJhN2YxOTgxOTcgPSAkKCc8ZGl2IGlkPSJodG1sXzE4YjYxM2Q3OWEyNzRjMTc4NTg5YjQyYTdmMTk4MTk3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA4OCBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84ZDZkMjM3OTBlZTM0NzM5OTI5MzFiOGM3YWZlMjkyZS5zZXRDb250ZW50KGh0bWxfMThiNjEzZDc5YTI3NGMxNzg1ODliNDJhN2YxOTgxOTcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWE2NTM4MTQwNGY3NDU3YTkxNmQ2YWZhODUyMDE4ZGIuYmluZFBvcHVwKHBvcHVwXzhkNmQyMzc5MGVlMzQ3Mzk5MjkzMWI4YzdhZmUyOTJlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MGY1NTdmYjg2Mjc0ODNkYjgwYWU5Y2RjOWQyMTFkYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMzNjIsIC03MS4xMDY3NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTE5NzkxYWM2YTUxNGIzNDhhM2I0MWIzZWQ4MDA4YmEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xZDg0MmExZmMxODA0ZDFmODgwZDMxMGEzYjA0ZjcwMyA9ICQoJzxkaXYgaWQ9Imh0bWxfMWQ4NDJhMWZjMTgwNGQxZjg4MGQzMTBhM2IwNGY3MDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDEyNyBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81MTk3OTFhYzZhNTE0YjM0OGEzYjQxYjNlZDgwMDhiYS5zZXRDb250ZW50KGh0bWxfMWQ4NDJhMWZjMTgwNGQxZjg4MGQzMTBhM2IwNGY3MDMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjBmNTU3ZmI4NjI3NDgzZGI4MGFlOWNkYzlkMjExZGMuYmluZFBvcHVwKHBvcHVwXzUxOTc5MWFjNmE1MTRiMzQ4YTNiNDFiM2VkODAwOGJhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MWQ4Y2M5MThkMDc0NWUzOTU3ZjE3MWI2MDk4NjQyMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMzNzYzLCAtNzEuMTA1MV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTJkZDc2YjhmZjExNGViYmI4ODBmYTNhNzc4N2U3YTUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMjU3YzhmMDc2ZmI0YWVkOGNiZjdlZjZjMWEzNzMzYyA9ICQoJzxkaXYgaWQ9Imh0bWxfYTI1N2M4ZjA3NmZiNGFlZDhjYmY3ZWY2YzFhMzczM2MiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDEyMCBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85MmRkNzZiOGZmMTE0ZWJiYjg4MGZhM2E3Nzg3ZTdhNS5zZXRDb250ZW50KGh0bWxfYTI1N2M4ZjA3NmZiNGFlZDhjYmY3ZWY2YzFhMzczM2MpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjFkOGNjOTE4ZDA3NDVlMzk1N2YxNzFiNjA5ODY0MjAuYmluZFBvcHVwKHBvcHVwXzkyZGQ3NmI4ZmYxMTRlYmJiODgwZmEzYTc3ODdlN2E1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xMDVkOGRhOGM3NmQ0ODVlYmIyNDkyYTk5ZjYzMGJkOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMzOTg3LCAtNzEuMTA0NTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzlkNjJjOTcwNDJjNDQ1NjU4ODZkZjFmYTRkNmM4MzUxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWJhNWM2MGUxMDkyNGFiNmI0MjE4ODQxZGU4NjE1NzAgPSAkKCc8ZGl2IGlkPSJodG1sXzFiYTVjNjBlMTA5MjRhYjZiNDIxODg0MWRlODYxNTcwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA0NiBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85ZDYyYzk3MDQyYzQ0NTY1ODg2ZGYxZmE0ZDZjODM1MS5zZXRDb250ZW50KGh0bWxfMWJhNWM2MGUxMDkyNGFiNmI0MjE4ODQxZGU4NjE1NzApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTA1ZDhkYThjNzZkNDg1ZWJiMjQ5MmE5OWY2MzBiZDkuYmluZFBvcHVwKHBvcHVwXzlkNjJjOTcwNDJjNDQ1NjU4ODZkZjFmYTRkNmM4MzUxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYmU3OTRkNmIyMWE0NGQ3ODlmMzI3NDgwZjEzOTA4NSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjM3NDgsIC03MS4xMDQyOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDk0ZjhlZWI4N2E2NDM3ZmIyOWI2ZDEyOGQ0MjZlYjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNTI2OWFmZDQzNzk0MDY2YjAzY2M0MDUzZmI2OTM2OCA9ICQoJzxkaXYgaWQ9Imh0bWxfZjUyNjlhZmQ0Mzc5NDA2NmIwM2NjNDA1M2ZiNjkzNjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDQyIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ5NGY4ZWViODdhNjQzN2ZiMjliNmQxMjhkNDI2ZWI0LnNldENvbnRlbnQoaHRtbF9mNTI2OWFmZDQzNzk0MDY2YjAzY2M0MDUzZmI2OTM2OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iYmU3OTRkNmIyMWE0NGQ3ODlmMzI3NDgwZjEzOTA4NS5iaW5kUG9wdXAocG9wdXBfNDk0ZjhlZWI4N2E2NDM3ZmIyOWI2ZDEyOGQ0MjZlYjQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NmNDQ0YjdhYjU2MjQ1NDk5MTM2OTE5NmFmNjMwYWYxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzI5NjUsIC03MS4xMDczOV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTNlZDYyM2IzNDIxNDFiODg4YzMzYTRiNDExYzk4NWEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MTQ1MzFmYTc0NWQ0MzQxYjE3Mjg1NDg4ZWFiZjU3ZSA9ICQoJzxkaXYgaWQ9Imh0bWxfNTE0NTMxZmE3NDVkNDM0MWIxNzI4NTQ4OGVhYmY1N2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDgxIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzkzZWQ2MjNiMzQyMTQxYjg4OGMzM2E0YjQxMWM5ODVhLnNldENvbnRlbnQoaHRtbF81MTQ1MzFmYTc0NWQ0MzQxYjE3Mjg1NDg4ZWFiZjU3ZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jZjQ0NGI3YWI1NjI0NTQ5OTEzNjkxOTZhZjYzMGFmMS5iaW5kUG9wdXAocG9wdXBfOTNlZDYyM2IzNDIxNDFiODg4YzMzYTRiNDExYzk4NWEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I4YzIxMzA2ZjJmZTQ3MTA4YWRlNWMzMWQ3MzNhNDFkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzY2NDQsIC03MS4wNTg3OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTZiZTcxMTU0NGJhNDZkMzhkMjlmZWY3YWM3N2FlNGIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lNWM0OGNiNGVhMDk0NmEzOTMyYWVjN2NjMjQ3OWIxOSA9ICQoJzxkaXYgaWQ9Imh0bWxfZTVjNDhjYjRlYTA5NDZhMzkzMmFlYzdjYzI0NzliMTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDY4IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U2YmU3MTE1NDRiYTQ2ZDM4ZDI5ZmVmN2FjNzdhZTRiLnNldENvbnRlbnQoaHRtbF9lNWM0OGNiNGVhMDk0NmEzOTMyYWVjN2NjMjQ3OWIxOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iOGMyMTMwNmYyZmU0NzEwOGFkZTVjMzFkNzMzYTQxZC5iaW5kUG9wdXAocG9wdXBfZTZiZTcxMTU0NGJhNDZkMzhkMjlmZWY3YWM3N2FlNGIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzc5MmU2Y2Y5MzQwNjRjYWE5OTNmNDFkOGQ1OGEzYzg1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzYzMDEsIC03MS4wMjU3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNGY5MTRiMTM0ZmQ5NGZkYTk0YmJjODkzNzI1ZTQ3ODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82MjdmNzM5Mjk5NDA0NTg3YWUyZmRkYmU2Yjk3NzUyMyA9ICQoJzxkaXYgaWQ9Imh0bWxfNjI3ZjczOTI5OTQwNDU4N2FlMmZkZGJlNmI5Nzc1MjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDEwNyBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80ZjkxNGIxMzRmZDk0ZmRhOTRiYmM4OTM3MjVlNDc4MC5zZXRDb250ZW50KGh0bWxfNjI3ZjczOTI5OTQwNDU4N2FlMmZkZGJlNmI5Nzc1MjMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzkyZTZjZjkzNDA2NGNhYTk5M2Y0MWQ4ZDU4YTNjODUuYmluZFBvcHVwKHBvcHVwXzRmOTE0YjEzNGZkOTRmZGE5NGJiYzg5MzcyNWU0NzgwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMWVkMjY5OGNlMWU0YTllODUxZmE2OTdmYTU4NDMxMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjI4OTM2LCAtNzEuMDcxOTZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdkMDVlYWZmODYzZDQ3ZjBhYzVkNDBhMmU1Nzk4MWNhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYzM3ZDNkYmI2OGVjNDRiYTlhYzYwYzRhOTA3YzY5NDIgPSAkKCc8ZGl2IGlkPSJodG1sX2MzN2QzZGJiNjhlYzQ0YmE5YWM2MGM0YTkwN2M2OTQyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA4MCBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83ZDA1ZWFmZjg2M2Q0N2YwYWM1ZDQwYTJlNTc5ODFjYS5zZXRDb250ZW50KGh0bWxfYzM3ZDNkYmI2OGVjNDRiYTlhYzYwYzRhOTA3YzY5NDIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzFlZDI2OThjZTFlNGE5ZTg1MWZhNjk3ZmE1ODQzMTEuYmluZFBvcHVwKHBvcHVwXzdkMDVlYWZmODYzZDQ3ZjBhYzVkNDBhMmU1Nzk4MWNhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mMmU5MTZjMTI2ZmI0ZDFjODIxZDY4YTE1Y2I3NjUzYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMzNDc5LCAtNzEuMDczMjldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RlNWU1OTllMjNiNjQyNzI4ZGUzNjU2ZmMwNjE3YmM5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjFhYzQxN2ZjMzFlNDc0YmI0ZjZkNjYzYWZmYzIyNTQgPSAkKCc8ZGl2IGlkPSJodG1sX2IxYWM0MTdmYzMxZTQ3NGJiNGY2ZDY2M2FmZmMyMjU0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA4MiBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kZTVlNTk5ZTIzYjY0MjcyOGRlMzY1NmZjMDYxN2JjOS5zZXRDb250ZW50KGh0bWxfYjFhYzQxN2ZjMzFlNDc0YmI0ZjZkNjYzYWZmYzIyNTQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZjJlOTE2YzEyNmZiNGQxYzgyMWQ2OGExNWNiNzY1M2IuYmluZFBvcHVwKHBvcHVwX2RlNWU1OTllMjNiNjQyNzI4ZGUzNjU2ZmMwNjE3YmM5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mMzM4ODg4OGVmNjI0MWM2Yjc1ODY5YTdmMzgyMjYzNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjQ2MDQxLCAtNzEuMDYxMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzgzNmY2NTUxYThhYzQxZjc5YmU5NDE0YjA5YzVjZjFkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjA4ZjU4YjkxY2QyNDcwNWIwZmY1ZDdmYWEyMTFmMWEgPSAkKCc8ZGl2IGlkPSJodG1sXzYwOGY1OGI5MWNkMjQ3MDViMGZmNWQ3ZmFhMjExZjFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSAxMjYgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODM2ZjY1NTFhOGFjNDFmNzliZTk0MTRiMDljNWNmMWQuc2V0Q29udGVudChodG1sXzYwOGY1OGI5MWNkMjQ3MDViMGZmNWQ3ZmFhMjExZjFhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YzMzg4ODg4ZWY2MjQxYzZiNzU4NjlhN2YzODIyNjM1LmJpbmRQb3B1cChwb3B1cF84MzZmNjU1MWE4YWM0MWY3OWJlOTQxNGIwOWM1Y2YxZCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmViNmNmNzU2MWM0NDIyNjlkYzRlMmM1MDUzYTM5YzYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNjMxNSwgLTcxLjA2ODgzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jY2E5ZjRhOGJhNjY0ZDRhYTRlZjQxNDhlNGNkMzQ2MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzkyOWU0NjU0NzE1ZDQwMDE5NWZhZDNiZjMyOGY4Nzk3ID0gJCgnPGRpdiBpZD0iaHRtbF85MjllNDY1NDcxNWQ0MDAxOTVmYWQzYmYzMjhmODc5NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTIyIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2NjYTlmNGE4YmE2NjRkNGFhNGVmNDE0OGU0Y2QzNDYyLnNldENvbnRlbnQoaHRtbF85MjllNDY1NDcxNWQ0MDAxOTVmYWQzYmYzMjhmODc5Nyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iZWI2Y2Y3NTYxYzQ0MjI2OWRjNGUyYzUwNTNhMzljNi5iaW5kUG9wdXAocG9wdXBfY2NhOWY0YThiYTY2NGQ0YWE0ZWY0MTQ4ZTRjZDM0NjIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y2ODdhMzJmNTUxYjQyNzRhMTZlOTRiNTU4N2VjYmZiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzUwMTUsIC03MS4xNDMzOV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmYyYTM3OWIxMGZlNGQyNzkyNDFjM2U2MGNmNGE1NzUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iMzBkZjg2OTYzNjk0ODcxOGE1MmQ0YjliMDk3NTFiYyA9ICQoJzxkaXYgaWQ9Imh0bWxfYjMwZGY4Njk2MzY5NDg3MThhNTJkNGI5YjA5NzUxYmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDU2IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzJmMmEzNzliMTBmZTRkMjc5MjQxYzNlNjBjZjRhNTc1LnNldENvbnRlbnQoaHRtbF9iMzBkZjg2OTYzNjk0ODcxOGE1MmQ0YjliMDk3NTFiYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mNjg3YTMyZjU1MWI0Mjc0YTE2ZTk0YjU1ODdlY2JmYi5iaW5kUG9wdXAocG9wdXBfMmYyYTM3OWIxMGZlNGQyNzkyNDFjM2U2MGNmNGE1NzUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2MzODBjNTAzNGMzNDQ4OGQ4MTM3MWUyYzk0MmU0MWUzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzQ4ODcsIC03MS4xNDczNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzdlNDY5YWNkMjE3NDk2NWJhNzQ1Zjk3OGRmMzMzZmEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83MTQ5NDhlZjc2ZTg0MGVkOTIwNTU2YWFkODcwMDVhYiA9ICQoJzxkaXYgaWQ9Imh0bWxfNzE0OTQ4ZWY3NmU4NDBlZDkyMDU1NmFhZDg3MDA1YWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDExMSBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jN2U0NjlhY2QyMTc0OTY1YmE3NDVmOTc4ZGYzMzNmYS5zZXRDb250ZW50KGh0bWxfNzE0OTQ4ZWY3NmU4NDBlZDkyMDU1NmFhZDg3MDA1YWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzM4MGM1MDM0YzM0NDg4ZDgxMzcxZTJjOTQyZTQxZTMuYmluZFBvcHVwKHBvcHVwX2M3ZTQ2OWFjZDIxNzQ5NjViYTc0NWY5NzhkZjMzM2ZhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jYjdhNmNhMjgyZjU0OWZkYTM5Nzg5NWMxNzNmMDBlZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjM2MzAyLCAtNzEuMDY2NThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzVkODUxZDZkYWVmZjQyNjE5NmFkYTBkMWVkYTBiMWIwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGM2YTBiMDNmOTE3NDNjYWExMzNlMmUxZmVkY2JmNDIgPSAkKCc8ZGl2IGlkPSJodG1sXzBjNmEwYjAzZjkxNzQzY2FhMTMzZTJlMWZlZGNiZjQyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSAyMSBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81ZDg1MWQ2ZGFlZmY0MjYxOTZhZGEwZDFlZGEwYjFiMC5zZXRDb250ZW50KGh0bWxfMGM2YTBiMDNmOTE3NDNjYWExMzNlMmUxZmVkY2JmNDIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfY2I3YTZjYTI4MmY1NDlmZGEzOTc4OTVjMTczZjAwZWUuYmluZFBvcHVwKHBvcHVwXzVkODUxZDZkYWVmZjQyNjE5NmFkYTBkMWVkYTBiMWIwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yOWI0MzFjMTQ3ZTQ0OTZjYjM5NmEzYmFkM2RiYjIyMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjM3Mzk3LCAtNzEuMTMzNDNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2QyMjEwMjBiOTg3ZjQ1MDE4ODZiYmVhZjljODAwYWYwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjg1NDIzNzRiNDc3NDk2Y2I3MjhiYmQyNDE2MDBkMmEgPSAkKCc8ZGl2IGlkPSJodG1sX2Y4NTQyMzc0YjQ3NzQ5NmNiNzI4YmJkMjQxNjAwZDJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSAyNyBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kMjIxMDIwYjk4N2Y0NTAxODg2YmJlYWY5YzgwMGFmMC5zZXRDb250ZW50KGh0bWxfZjg1NDIzNzRiNDc3NDk2Y2I3MjhiYmQyNDE2MDBkMmEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjliNDMxYzE0N2U0NDk2Y2IzOTZhM2JhZDNkYmIyMjMuYmluZFBvcHVwKHBvcHVwX2QyMjEwMjBiOTg3ZjQ1MDE4ODZiYmVhZjljODAwYWYwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMzhmN2EzZjIxNDY0Y2IyODhkNzdiOGMyMjkzYTdlNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjMyNjk4LCAtNzEuMTEwNjNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzkxZmRiMmQwNmE0ZjRmYTY4YTUzZmY0MmUxMTJhNzI2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDgzYTQ1M2UzMWNjNGViMDhkNjEwM2EwMmFkNTk2MTggPSAkKCc8ZGl2IGlkPSJodG1sXzA4M2E0NTNlMzFjYzRlYjA4ZDYxMDNhMDJhZDU5NjE4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSA0NCBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85MWZkYjJkMDZhNGY0ZmE2OGE1M2ZmNDJlMTEyYTcyNi5zZXRDb250ZW50KGh0bWxfMDgzYTQ1M2UzMWNjNGViMDhkNjEwM2EwMmFkNTk2MTgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjM4ZjdhM2YyMTQ2NGNiMjg4ZDc3YjhjMjI5M2E3ZTcuYmluZFBvcHVwKHBvcHVwXzkxZmRiMmQwNmE0ZjRmYTY4YTUzZmY0MmUxMTJhNzI2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82YjFjODQwOTZhOGQ0ZDFiYTRkNDViOWViY2Y3NWIzNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjQyNjI5LCAtNzEuMTExMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGJkMDRiZWY2NDYyNGMyYWJlZTE2NDRiNTM0ZDU4YmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNjVjZDlmNzQzNDE0MTJiOTBlM2NlZGJhOWIwMzYxZiA9ICQoJzxkaXYgaWQ9Imh0bWxfZjY1Y2Q5Zjc0MzQxNDEyYjkwZTNjZWRiYTliMDM2MWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDggTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZGJkMDRiZWY2NDYyNGMyYWJlZTE2NDRiNTM0ZDU4YmYuc2V0Q29udGVudChodG1sX2Y2NWNkOWY3NDM0MTQxMmI5MGUzY2VkYmE5YjAzNjFmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzZiMWM4NDA5NmE4ZDRkMWJhNGQ0NWI5ZWJjZjc1YjM1LmJpbmRQb3B1cChwb3B1cF9kYmQwNGJlZjY0NjI0YzJhYmVlMTY0NGI1MzRkNThiZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTlhZjQ3MDMyNzU2NGUxMTliMjM4YTM0YTBjOWUzODQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNTAzNSwgLTcxLjA2Mzc1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80YmEyMjJjNGE5YTY0MWQwYTAyN2RhNzhiNDJiMWYyNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzVkMzExOTVmNmIyNjQxMTM4MDRmNDhmOGE5YTg4MmRkID0gJCgnPGRpdiBpZD0iaHRtbF81ZDMxMTk1ZjZiMjY0MTEzODA0ZjQ4ZjhhOWE4ODJkZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gOTkgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGJhMjIyYzRhOWE2NDFkMGEwMjdkYTc4YjQyYjFmMjQuc2V0Q29udGVudChodG1sXzVkMzExOTVmNmIyNjQxMTM4MDRmNDhmOGE5YTg4MmRkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU5YWY0NzAzMjc1NjRlMTE5YjIzOGEzNGEwYzllMzg0LmJpbmRQb3B1cChwb3B1cF80YmEyMjJjNGE5YTY0MWQwYTAyN2RhNzhiNDJiMWYyNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTI4MzJmZTBmYzY5NGFiMjgyMDZlYjRkYTMwOThjMDIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zOTYxNCwgLTcxLjAzOTE0XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zNzg2NGM0ODc2NTc0NzM5YmRhMTNmNWE0MjkzODcyNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY2YTk3MmFhMzUzYjRhOWNiYjJkYzA2ZGI0ZjM2YmMxID0gJCgnPGRpdiBpZD0iaHRtbF82NmE5NzJhYTM1M2I0YTljYmIyZGMwNmRiNGYzNmJjMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMzQgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzc4NjRjNDg3NjU3NDczOWJkYTEzZjVhNDI5Mzg3MjUuc2V0Q29udGVudChodG1sXzY2YTk3MmFhMzUzYjRhOWNiYjJkYzA2ZGI0ZjM2YmMxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzkyODMyZmUwZmM2OTRhYjI4MjA2ZWI0ZGEzMDk4YzAyLmJpbmRQb3B1cChwb3B1cF8zNzg2NGM0ODc2NTc0NzM5YmRhMTNmNWE0MjkzODcyNSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjNkM2MyZjE3NmZiNDgxMWFmMTc3MzYyNDgyODBkNjAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNjI3MywgLTcxLjA3MDExXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hNTZmNzAyYjBmMmU0NWU2YWYzOWMxMTNhOWIyNmExZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQwOWE0YTdlNTliMDQ0Y2U4MzhkMWU0OWVkMTYzNTY4ID0gJCgnPGRpdiBpZD0iaHRtbF80MDlhNGE3ZTU5YjA0NGNlODM4ZDFlNDllZDE2MzU2OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTE0IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E1NmY3MDJiMGYyZTQ1ZTZhZjM5YzExM2E5YjI2YTFkLnNldENvbnRlbnQoaHRtbF80MDlhNGE3ZTU5YjA0NGNlODM4ZDFlNDllZDE2MzU2OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iM2QzYzJmMTc2ZmI0ODExYWYxNzczNjI0ODI4MGQ2MC5iaW5kUG9wdXAocG9wdXBfYTU2ZjcwMmIwZjJlNDVlNmFmMzljMTEzYTliMjZhMWQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RhNDJiZDA1NWEzZTRmZDE5YjhhODllYTY1NGZmYWY1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzUwNTQsIC03MS4wNzY3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjhhMDU3ZGExNGQ3NDYzYjhiN2E1MDE4ZGUzODY0YmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNjkzMzk4YzA3MjA0YmUwODYwZTIwZDBjOTk0ZjFmNCA9ICQoJzxkaXYgaWQ9Imh0bWxfZjY5MzM5OGMwNzIwNGJlMDg2MGUyMGQwYzk5NGYxZjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDIzIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I4YTA1N2RhMTRkNzQ2M2I4YjdhNTAxOGRlMzg2NGJjLnNldENvbnRlbnQoaHRtbF9mNjkzMzk4YzA3MjA0YmUwODYwZTIwZDBjOTk0ZjFmNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kYTQyYmQwNTVhM2U0ZmQxOWI4YTg5ZWE2NTRmZmFmNS5iaW5kUG9wdXAocG9wdXBfYjhhMDU3ZGExNGQ3NDYzYjhiN2E1MDE4ZGUzODY0YmMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzRiOTVhY2EzMDY3MDQ0NTlhNjRlMjAwZTU1NDVjYzMzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzAxNjQsIC03MS4xMjg3OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzBjNjg0ODYxOWMzNGE4YzkxMTNlZjNlMTczOTFlNTMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84OWJiNDMzMDQ2YTI0NjlmOTA5YjlhNTc4YzBhOTE2OCA9ICQoJzxkaXYgaWQ9Imh0bWxfODliYjQzMzA0NmEyNDY5ZjkwOWI5YTU3OGMwYTkxNjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDg4IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2MwYzY4NDg2MTljMzRhOGM5MTEzZWYzZTE3MzkxZTUzLnNldENvbnRlbnQoaHRtbF84OWJiNDMzMDQ2YTI0NjlmOTA5YjlhNTc4YzBhOTE2OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80Yjk1YWNhMzA2NzA0NDU5YTY0ZTIwMGU1NTQ1Y2MzMy5iaW5kUG9wdXAocG9wdXBfYzBjNjg0ODYxOWMzNGE4YzkxMTNlZjNlMTczOTFlNTMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4ZjI4MGMxMjY0YTQ4MzQ4Zjc3MWRlODMyNjYyNmIzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzM2MiwgLTcxLjEwNjc0XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYTU0NTI4NDU1OGY0ZDRhYTE3NTlmM2JiMTgyNGQ4ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY3ZDBjNThkMGZkYjQwMmQ5ZTBiMzMxM2IyM2UxM2EzID0gJCgnPGRpdiBpZD0iaHRtbF82N2QwYzU4ZDBmZGI0MDJkOWUwYjMzMTNiMjNlMTNhMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTI3IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RhNTQ1Mjg0NTU4ZjRkNGFhMTc1OWYzYmIxODI0ZDhmLnNldENvbnRlbnQoaHRtbF82N2QwYzU4ZDBmZGI0MDJkOWUwYjMzMTNiMjNlMTNhMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mOGYyODBjMTI2NGE0ODM0OGY3NzFkZTgzMjY2MjZiMy5iaW5kUG9wdXAocG9wdXBfZGE1NDUyODQ1NThmNGQ0YWExNzU5ZjNiYjE4MjRkOGYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y5ZGJkNGMwMzk4MDRiZGZiMmFhYmUzZGNkMTFiMzYwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzM3NjMsIC03MS4xMDUxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNWU3MzA5OTUxZGY0MzhhOWNiZThiNjg3NjAzYjU4NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBiMzExZmI1OWViYjQ0NWNiYTM0M2M4ODE1MzYxZTQ1ID0gJCgnPGRpdiBpZD0iaHRtbF8wYjMxMWZiNTllYmI0NDVjYmEzNDNjODgxNTM2MWU0NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTIwIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M1ZTczMDk5NTFkZjQzOGE5Y2JlOGI2ODc2MDNiNTg2LnNldENvbnRlbnQoaHRtbF8wYjMxMWZiNTllYmI0NDVjYmEzNDNjODgxNTM2MWU0NSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mOWRiZDRjMDM5ODA0YmRmYjJhYWJlM2RjZDExYjM2MC5iaW5kUG9wdXAocG9wdXBfYzVlNzMwOTk1MWRmNDM4YTljYmU4YjY4NzYwM2I1ODYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2M0MDExNTYzNzYxNTQ4NWI5NTdlMGIyMDcyYWJjYWJiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzM5ODcsIC03MS4xMDQ1NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWRkMTg2ZGQ2MWRmNDdiNTkxYjZlMTRjNDQyYjQxN2EgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MjEzNWRlNjhkZmU0YzlhYTRhNGYyZWNmOGRhMzQ2NiA9ICQoJzxkaXYgaWQ9Imh0bWxfNTIxMzVkZTY4ZGZlNGM5YWE0YTRmMmVjZjhkYTM0NjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDQ2IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FkZDE4NmRkNjFkZjQ3YjU5MWI2ZTE0YzQ0MmI0MTdhLnNldENvbnRlbnQoaHRtbF81MjEzNWRlNjhkZmU0YzlhYTRhNGYyZWNmOGRhMzQ2Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jNDAxMTU2Mzc2MTU0ODViOTU3ZTBiMjA3MmFiY2FiYi5iaW5kUG9wdXAocG9wdXBfYWRkMTg2ZGQ2MWRmNDdiNTkxYjZlMTRjNDQyYjQxN2EpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzcwMjczYjlkOGJiYzQ3MzBiMzdkMjEwZjUzMGE1OGJjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzc0OCwgLTcxLjEwNDI4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mNDgwOTcxYWI3ZjU0MGU5YmRhY2JkNzBkMzNhNmJhOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMxZjBiNDMzOGEyNjQ0MjRiMGI4OWJmNThlZmZmZWViID0gJCgnPGRpdiBpZD0iaHRtbF8zMWYwYjQzMzhhMjY0NDI0YjBiODliZjU4ZWZmZmVlYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gNDIgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjQ4MDk3MWFiN2Y1NDBlOWJkYWNiZDcwZDMzYTZiYTkuc2V0Q29udGVudChodG1sXzMxZjBiNDMzOGEyNjQ0MjRiMGI4OWJmNThlZmZmZWViKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzcwMjczYjlkOGJiYzQ3MzBiMzdkMjEwZjUzMGE1OGJjLmJpbmRQb3B1cChwb3B1cF9mNDgwOTcxYWI3ZjU0MGU5YmRhY2JkNzBkMzNhNmJhOSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWJlYzA1NWIzOGY0NDUzZDg0YzIwYzg0Yjk0YzRiMGEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zMjk2NSwgLTcxLjEwNzM5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hYzRjMDY5ZGM4NWE0OGRhOWZhYmVlNzRlOTFlMWU4NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUxOWVmZDVjZjZhYTRmMjY5ZTFhZDgzYzMwNzNjYTAxID0gJCgnPGRpdiBpZD0iaHRtbF81MTllZmQ1Y2Y2YWE0ZjI2OWUxYWQ4M2MzMDczY2EwMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gODEgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYWM0YzA2OWRjODVhNDhkYTlmYWJlZTc0ZTkxZTFlODcuc2V0Q29udGVudChodG1sXzUxOWVmZDVjZjZhYTRmMjY5ZTFhZDgzYzMwNzNjYTAxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFiZWMwNTViMzhmNDQ1M2Q4NGMyMGM4NGI5NGM0YjBhLmJpbmRQb3B1cChwb3B1cF9hYzRjMDY5ZGM4NWE0OGRhOWZhYmVlNzRlOTFlMWU4NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmEwYmQ5ODVmMGEzNDdlMjg4YWY4MzEyMjMxNDM5YzggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNjY0NCwgLTcxLjA1ODc4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80MzU3ZGE3NTNjYTk0MDQ4YTY3Yzc3ODNiNmI2ZmYzNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZjYmVkODY0OTdlMjRmZDY4MjRkMGUyZmE5MTc5NWE0ID0gJCgnPGRpdiBpZD0iaHRtbF9mY2JlZDg2NDk3ZTI0ZmQ2ODI0ZDBlMmZhOTE3OTVhNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gNjggTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDM1N2RhNzUzY2E5NDA0OGE2N2M3NzgzYjZiNmZmMzQuc2V0Q29udGVudChodG1sX2ZjYmVkODY0OTdlMjRmZDY4MjRkMGUyZmE5MTc5NWE0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2ZhMGJkOTg1ZjBhMzQ3ZTI4OGFmODMxMjIzMTQzOWM4LmJpbmRQb3B1cChwb3B1cF80MzU3ZGE3NTNjYTk0MDQ4YTY3Yzc3ODNiNmI2ZmYzNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjZjZmRmZDMxNzk0NGY1MjkwNDUxZDc2NzRmNmU1YzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNjMwMSwgLTcxLjAyNTcyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mNDJiNWViMDQzYzI0YmViYTg0MDc5ZmYyZjY1MWZiNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Y2YjgxOTkyYjgzZTRjNGNiNGNmMWQ0YzEyODY5Y2VkID0gJCgnPGRpdiBpZD0iaHRtbF9mNmI4MTk5MmI4M2U0YzRjYjRjZjFkNGMxMjg2OWNlZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTA3IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Y0MmI1ZWIwNDNjMjRiZWJhODQwNzlmZjJmNjUxZmI0LnNldENvbnRlbnQoaHRtbF9mNmI4MTk5MmI4M2U0YzRjYjRjZjFkNGMxMjg2OWNlZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yNmNmZGZkMzE3OTQ0ZjUyOTA0NTFkNzY3NGY2ZTVjMS5iaW5kUG9wdXAocG9wdXBfZjQyYjVlYjA0M2MyNGJlYmE4NDA3OWZmMmY2NTFmYjQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2VkZmY5NTk0YmQ2OTRkMmJhZjg3NmQzMjE0NWViMjYzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMjg5MzYsIC03MS4wNzE5Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMGI2N2I0OWE4YjA3NDNiMzlmZTkzZTJmYmM2ODA0MTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jZTRjNDU4MDE5N2I0ZmMxYWRlZDcwZTI4MjUxYWE4NiA9ICQoJzxkaXYgaWQ9Imh0bWxfY2U0YzQ1ODAxOTdiNGZjMWFkZWQ3MGUyODI1MWFhODYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDgwIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzBiNjdiNDlhOGIwNzQzYjM5ZmU5M2UyZmJjNjgwNDEwLnNldENvbnRlbnQoaHRtbF9jZTRjNDU4MDE5N2I0ZmMxYWRlZDcwZTI4MjUxYWE4Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lZGZmOTU5NGJkNjk0ZDJiYWY4NzZkMzIxNDVlYjI2My5iaW5kUG9wdXAocG9wdXBfMGI2N2I0OWE4YjA3NDNiMzlmZTkzZTJmYmM2ODA0MTApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzZkMTYzOTE1ZjdkNzQwZWRiNTA3MGZjOWM2MTFkOGVhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzM0NzksIC03MS4wNzMyOV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzY1NDM1ZWFhYjU2NDQwOGE2ZTM4YmZhZjU0NTkwMDcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lZTc2YmUzMmY3MTI0Y2M4YmNmNjViYWNmMTNjMmYyMyA9ICQoJzxkaXYgaWQ9Imh0bWxfZWU3NmJlMzJmNzEyNGNjOGJjZjY1YmFjZjEzYzJmMjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDgyIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M2NTQzNWVhYWI1NjQ0MDhhNmUzOGJmYWY1NDU5MDA3LnNldENvbnRlbnQoaHRtbF9lZTc2YmUzMmY3MTI0Y2M4YmNmNjViYWNmMTNjMmYyMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82ZDE2MzkxNWY3ZDc0MGVkYjUwNzBmYzljNjExZDhlYS5iaW5kUG9wdXAocG9wdXBfYzY1NDM1ZWFhYjU2NDQwOGE2ZTM4YmZhZjU0NTkwMDcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q5OGQzYmE3MzRiZTRmMmVhOThmZjlkOTAxZDM0N2QzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuNDYwNDEsIC03MS4wNjEwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjc5NjliMTg5ZWRiNDk0M2FjMjVhN2RiMzVjMzllNTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lYTYwMzZmNzM0MGY0NjZmYjQwZWE0NTYyYmRhNjgxNSA9ICQoJzxkaXYgaWQ9Imh0bWxfZWE2MDM2ZjczNDBmNDY2ZmI0MGVhNDU2MmJkYTY4MTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDEyNiBOYW1lOiByZXNvdXJjZS5uYW1lLCBkdHlwZTogb2JqZWN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNzk2OWIxODllZGI0OTQzYWMyNWE3ZGIzNWMzOWU1OS5zZXRDb250ZW50KGh0bWxfZWE2MDM2ZjczNDBmNDY2ZmI0MGVhNDU2MmJkYTY4MTUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZDk4ZDNiYTczNGJlNGYyZWE5OGZmOWQ5MDFkMzQ3ZDMuYmluZFBvcHVwKHBvcHVwX2I3OTY5YjE4OWVkYjQ5NDNhYzI1YTdkYjM1YzM5ZTU5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMTE5OTliYmQxYjI0N2FjODk4MDZiZjBjZDgyN2E5YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQyLjM2MzE1LCAtNzEuMDY4ODNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzMzODhmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogInJlZCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzYzMDcwNmFkMGMyNTQ0MjViMmJkNTc3ZTJmZmU0Mzk0KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M5MmYzOTZmNzk2OTRkZDhiY2M5YTljM2VjMzk3Y2MyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWZkNTRjYzIzNTM5NDRhMDkxZjdlNTFjODhhZWU1YWQgPSAkKCc8ZGl2IGlkPSJodG1sX2VmZDU0Y2MyMzUzOTQ0YTA5MWY3ZTUxYzg4YWVlNWFkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4wICAgIFN5bnRoZXRpYyBNYXNzIC0gTG9jYXRpb24gLSAxMjIgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzkyZjM5NmY3OTY5NGRkOGJjYzlhOWMzZWMzOTdjYzIuc2V0Q29udGVudChodG1sX2VmZDU0Y2MyMzUzOTQ0YTA5MWY3ZTUxYzg4YWVlNWFkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2MxMTk5OWJiZDFiMjQ3YWM4OTgwNmJmMGNkODI3YTljLmJpbmRQb3B1cChwb3B1cF9jOTJmMzk2Zjc5Njk0ZGQ4YmNjOWE5YzNlYzM5N2NjMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDU1OTA2OTcyMDMzNDM5YmE3YTAzNzFkYTg5ZDhkOWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNTAxNSwgLTcxLjE0MzM5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81Zjc3ZmQ5MTE3ZWU0YTUzOGRjN2E4Yjc5MmEwYzQ4NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcyNjFhOTgxMjg3ZjQ4MDQ4YmUyY2M3YjIxM2U3NDQ3ID0gJCgnPGRpdiBpZD0iaHRtbF83MjYxYTk4MTI4N2Y0ODA0OGJlMmNjN2IyMTNlNzQ0NyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gNTYgTmFtZTogcmVzb3VyY2UubmFtZSwgZHR5cGU6IG9iamVjdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNWY3N2ZkOTExN2VlNGE1MzhkYzdhOGI3OTJhMGM0ODcuc2V0Q29udGVudChodG1sXzcyNjFhOTgxMjg3ZjQ4MDQ4YmUyY2M3YjIxM2U3NDQ3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQ1NTkwNjk3MjAzMzQzOWJhN2EwMzcxZGE4OWQ4ZDliLmJpbmRQb3B1cChwb3B1cF81Zjc3ZmQ5MTE3ZWU0YTUzOGRjN2E4Yjc5MmEwYzQ4NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmM5MGI0ZmEzZjM2NDMzY2E0ZDRlZWU2NmY1OWMwYWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0Mi4zNDg4NywgLTcxLjE0NzM1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMzMzg4ZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICJyZWQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgLmFkZFRvKG1hcF82MzA3MDZhZDBjMjU0NDI1YjJiZDU3N2UyZmZlNDM5NCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82N2EyMDQwZWM2NjQ0MTMyOTE2NmQxZDRiNjg1YmYxZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzFmN2MxMjczN2MyNzQ4ODVhNzBlZjQ5MmNjOGNjZTRiID0gJCgnPGRpdiBpZD0iaHRtbF8xZjdjMTI3MzdjMjc0ODg1YTcwZWY0OTJjYzhjY2U0YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MCAgICBTeW50aGV0aWMgTWFzcyAtIExvY2F0aW9uIC0gMTExIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY3YTIwNDBlYzY2NDQxMzI5MTY2ZDFkNGI2ODViZjFmLnNldENvbnRlbnQoaHRtbF8xZjdjMTI3MzdjMjc0ODg1YTcwZWY0OTJjYzhjY2U0Yik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mYzkwYjRmYTNmMzY0MzNjYTRkNGVlZTY2ZjU5YzBhYy5iaW5kUG9wdXAocG9wdXBfNjdhMjA0MGVjNjY0NDEzMjkxNjZkMWQ0YjY4NWJmMWYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhlMjUwOWVlMDA0NjQ2NTJiNzg5MWZiYjQzNWFhZTAyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzYzMDIsIC03MS4wNjY1OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDJhZGE0NjgwNzc4NGQwMDg0OGY2MjRhZTYxZDFmMTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84Yzg5MDRmYTc2N2M0ZWViOWVmZjVlNWZkMjQ1MDY1MiA9ICQoJzxkaXYgaWQ9Imh0bWxfOGM4OTA0ZmE3NjdjNGVlYjllZmY1ZTVmZDI0NTA2NTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDIxIE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QyYWRhNDY4MDc3ODRkMDA4NDhmNjI0YWU2MWQxZjEwLnNldENvbnRlbnQoaHRtbF84Yzg5MDRmYTc2N2M0ZWViOWVmZjVlNWZkMjQ1MDY1Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84ZTI1MDllZTAwNDY0NjUyYjc4OTFmYmI0MzVhYWUwMi5iaW5kUG9wdXAocG9wdXBfZDJhZGE0NjgwNzc4NGQwMDg0OGY2MjRhZTYxZDFmMTApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzAwNWFiZTRjYWYyMDQ2ZWI4YWEwMjJmY2YyOTFlYTdjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDIuMzczOTcsIC03MS4xMzM0M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMzM4OGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAicmVkIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIC5hZGRUbyhtYXBfNjMwNzA2YWQwYzI1NDQyNWIyYmQ1NzdlMmZmZTQzOTQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmE5YjBjNDJkOWYzNGMxN2E4MjE0ZGIxN2I5MDI2YWUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lMzk2MzJhYWRlMGY0OTIwYTkzYWI2ZDM4MWQ5MTU0MiA9ICQoJzxkaXYgaWQ9Imh0bWxfZTM5NjMyYWFkZTBmNDkyMGE5M2FiNmQzODFkOTE1NDIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjAgICAgU3ludGhldGljIE1hc3MgLSBMb2NhdGlvbiAtIDI3IE5hbWU6IHJlc291cmNlLm5hbWUsIGR0eXBlOiBvYmplY3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZhOWIwYzQyZDlmMzRjMTdhODIxNGRiMTdiOTAyNmFlLnNldENvbnRlbnQoaHRtbF9lMzk2MzJhYWRlMGY0OTIwYTkzYWI2ZDM4MWQ5MTU0Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wMDVhYmU0Y2FmMjA0NmViOGFhMDIyZmNmMjkxZWE3Yy5iaW5kUG9wdXAocG9wdXBfNmE5YjBjNDJkOWYzNGMxN2E4MjE0ZGIxN2I5MDI2YWUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x12f1e9ad0>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# zoom 15 is used to show the groupings\n",
"cambridge = [ 42.373611, -71.11000]\n",
"map_cambridge_locs_from_server = folium.Map(location=cambridge, zoom_start=10)\n",
"\n",
"# Iterate through the Rows\n",
"for location_row in location_rows :\n",
" # print(location_row)\n",
" \n",
" # Cast the values into the appropriate types as FOLIUM will die weirdly without it. \n",
" lat_inc = float(location_row['resource.position.latitude'])\n",
" long_inc = float(location_row['resource.position.longitude'])\n",
" name_inc = str(location_row['resource.name'])\n",
" \n",
" #print(lat_inc)\n",
" #print(long_inc)\n",
" #print(name_inc)\n",
" \n",
" label = folium.Popup(name_inc, parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat_inc, long_inc],\n",
" radius=5,\n",
" popup=label,\n",
" fill=True,\n",
" fill_color='red',\n",
" fill_opacity=0.7).add_to(map_cambridge_locs_from_server)\n",
" \n",
"map_cambridge_locs_from_server"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(C) Copyright IBM Corp. 2020\n",
"\n",
"SPDX-License-Identifier: Apache-2.0"
]
}
],
"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.7.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@prb112
Copy link
Author

prb112 commented Nov 23, 2020

In order to visualize the response, the notebook generates output like the following:
image

The above gist requires Jupyter, Docker and the IBM FHIR Server. However, the near search should be supported on most implementations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment