Skip to content

Instantly share code, notes, and snippets.

@sofia100
Created May 25, 2020 07:46
Show Gist options
  • Save sofia100/c0d460671504a67762b42d613282763a to your computer and use it in GitHub Desktop.
Save sofia100/c0d460671504a67762b42d613282763a to your computer and use it in GitHub Desktop.
Created on Skills Network Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Alcoholic spaces Scanner"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this project I have pointed out the places in Bucharest that are alcoholic or not for teenagers less than 18 years old.\n",
"\n",
"There are many parents who want their children to be safe and practice the rules and regulations of the country. they should not be drinking before the legal age of the country. In this project I have made an analysis about various places that are suitable for the youth as well as the drinking sites.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Data\n",
"Data was available at wikipedia for Bucharest\n",
"\n",
"Links are:\n",
"\n",
"- \"https://en.wikipedia.org/wiki/Category:Districts_of_Bucharest\"\n",
"\n",
"- \"https://en.wikipedia.org/wiki/Sectors_of_Bucharest\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Installing libraries and packages"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: geopy in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (1.22.0)\n",
"Requirement already satisfied: geographiclib<2,>=1.49 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geopy) (1.50)\n",
"Requirement already satisfied: folium in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (0.5.0)\n",
"Requirement already satisfied: requests in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from folium) (2.23.0)\n",
"Requirement already satisfied: six in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from folium) (1.14.0)\n",
"Requirement already satisfied: branca in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from folium) (0.4.1)\n",
"Requirement already satisfied: jinja2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from folium) (2.11.2)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->folium) (2020.4.5.1)\n",
"Requirement already satisfied: chardet<4,>=3.0.2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->folium) (3.0.4)\n",
"Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->folium) (1.25.9)\n",
"Requirement already satisfied: idna<3,>=2.5 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->folium) (2.9)\n",
"Requirement already satisfied: MarkupSafe>=0.23 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from jinja2->folium) (1.1.1)\n",
"Requirement already satisfied: geocoder in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (1.38.1)\n",
"Requirement already satisfied: click in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (7.1.2)\n",
"Requirement already satisfied: requests in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (2.23.0)\n",
"Requirement already satisfied: six in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (1.14.0)\n",
"Requirement already satisfied: ratelim in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (0.1.6)\n",
"Requirement already satisfied: future in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (0.18.2)\n",
"Requirement already satisfied: chardet<4,>=3.0.2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (3.0.4)\n",
"Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (1.25.9)\n",
"Requirement already satisfied: certifi>=2017.4.17 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (2020.4.5.1)\n",
"Requirement already satisfied: idna<3,>=2.5 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (2.9)\n",
"Requirement already satisfied: decorator in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from ratelim->geocoder) (4.4.2)\n"
]
}
],
"source": [
"#install libraries \n",
"!pip install geopy \n",
"!pip install folium \n",
"!pip install geocoder"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: lxml in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (4.5.1)\n",
"Note: you may need to restart the kernel to use updated packages.\n"
]
}
],
"source": [
"pip install lxml"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: BeautifulSoup4 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (4.9.1)\n",
"Requirement already satisfied: soupsieve>1.2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from BeautifulSoup4) (2.0.1)\n"
]
}
],
"source": [
"!pip install BeautifulSoup4"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Libraries imported.\n"
]
}
],
"source": [
"#import libraries \n",
"import numpy as np # library to handle data in a vectorized manner\n",
"\n",
"import pandas as pd # library for data analsysis\n",
"pd.set_option('display.max_columns', None)\n",
"pd.set_option('display.max_rows', None)\n",
"\n",
"import matplotlib.pyplot as plt # for graphical usage \n",
"\n",
"import json # library to handle JSON files\n",
"\n",
"from geopy.geocoders import Nominatim # convert an address into latitude and longitude values\n",
"\n",
"from geopy.geocoders import Nominatim # convert an address into latitude and longitude values\n",
"import geocoder # to get coordinates\n",
"\n",
"import requests # library to handle requests\n",
"from pandas.io.json import json_normalize # tranform JSON file into a pandas dataframe\n",
"\n",
"# Matplotlib and associated plotting modules\n",
"import matplotlib.cm as cm\n",
"import matplotlib.colors as colors\n",
"\n",
"# import k-means from clustering stage\n",
"from sklearn.cluster import KMeans\n",
"\n",
"import folium # map rendering library\n",
"from folium import plugins\n",
"from folium.plugins import HeatMap\n",
"\n",
"# main documentation page: http://beautiful-soup-4.readthedocs.io/en/latest/\n",
"# how to use the BeautifulSoup package: https://www.youtube.com/watch?v=ng2o98k983k video\n",
"from bs4 import BeautifulSoup \n",
"import pandas as pd\n",
"import requests\n",
"\n",
"print('Libraries imported.')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The geograpical coordinate of Bucharest, Romania are 44.4361414, 26.1027202.\n"
]
}
],
"source": [
"# get coordinates of Bucharest\n",
"bucharest_address = 'Bucharest, Romania'\n",
"\n",
"geolocator = Nominatim(user_agent=\"bucharest1_explorer\")\n",
"location = geolocator.geocode(bucharest_address)\n",
"latitude = location.latitude\n",
"longitude = location.longitude\n",
"bucharest_center = [latitude, longitude ]\n",
"print('The geograpical coordinate of {} are {}, {}.'.format(bucharest_address, latitude, longitude))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 40 neighborhoods in Bucharest, Romania\n"
]
}
],
"source": [
"# Read Bucharest neighborhood data \n",
"url = \"https://en.wikipedia.org/wiki/Category:Districts of Bucharest\"\n",
"source = requests.get(url).text\n",
"soup = BeautifulSoup(source,'lxml')\n",
"\n",
"neighborhoodList = []\n",
"\n",
"# append the data into the list\n",
"for row in soup.find_all(\"div\", class_=\"mw-category\")[0].findAll(\"li\"):\n",
" neighborhoodList.append(row.text.replace(', Bucharest',''))\n",
" \n",
"df_neighborhood = pd.DataFrame({\"Neighborhood\": neighborhoodList})\n",
"print(\"There are {} neighborhoods in {}\".format(df_neighborhood.shape[0], bucharest_address))"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 6 Sector in Bucharest, Romania\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Sector</th>\n",
" <th>Neigborhoods</th>\n",
" <th>Population</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Sector 1</td>\n",
" <td>Dorobanți, Băneasa, Aviației, Pipera, Aviator...</td>\n",
" <td>225,454</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Sector 2</td>\n",
" <td>Pantelimon, Colentina, Iancului, Tei, Floreas...</td>\n",
" <td>345,370</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Sector 3</td>\n",
" <td>Vitan, Dudești, Titan, Centrul Civic, Balta A...</td>\n",
" <td>385,439</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Sector 4</td>\n",
" <td>Berceni, Olteniței, Văcărești, Timpuri Noi, T...</td>\n",
" <td>287,828</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Sector 5</td>\n",
" <td>Rahova, Ferentari, Giurgiului, Cotroceni, 13 ...</td>\n",
" <td>271,575</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Sector 6</td>\n",
" <td>Giulești, Crângași, Drumul Taberei, Militari,...</td>\n",
" <td>367,760</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Sector Neigborhoods Population\n",
"0 Sector 1 Dorobanți, Băneasa, Aviației, Pipera, Aviator... 225,454\n",
"1 Sector 2 Pantelimon, Colentina, Iancului, Tei, Floreas... 345,370\n",
"2 Sector 3 Vitan, Dudești, Titan, Centrul Civic, Balta A... 385,439\n",
"3 Sector 4 Berceni, Olteniței, Văcărești, Timpuri Noi, T... 287,828\n",
"4 Sector 5 Rahova, Ferentari, Giurgiului, Cotroceni, 13 ... 271,575\n",
"5 Sector 6 Giulești, Crângași, Drumul Taberei, Militari,... 367,760"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Read Bucharest sector data from wikipedia\n",
"url = \"https://en.wikipedia.org/wiki/Sectors_of_Bucharest\"\n",
"source = requests.get(url).text\n",
"soup = BeautifulSoup(source,'lxml')\n",
"\n",
"sectorPopList = []\n",
"sectorPopulationList = []\n",
"\n",
"for row in soup.find_all(\"tbody\"):\n",
" header = str(row.findAll(\"th\"))\n",
" if \"Population (October 2011)\" in header:\n",
" i = 0\n",
" for td in row.find_all(\"td\"):\n",
" i+=1\n",
" if i==2: \n",
" sectorPopList.append(td.text.replace(\"\\n\",\"\"))\n",
" if i==3: \n",
" sectorPopulationList.append(td.text.replace(\"\\n\",\"\")) \n",
" i=0\n",
"\n",
"df_sectorPop = pd.DataFrame({\"Sector\": sectorPopList, \"Population\": sectorPopulationList})\n",
"\n",
"sectorNeigList =[]\n",
"sectorNeigborList =[]\n",
"\n",
"for row in soup.find_all(\"ul\"):\n",
" if sectorPopList[0] in row.text:\n",
" for s in row.text.split(\"\\n\"):\n",
" sectorNeigList.append(s.split(\":\")[0])\n",
" sectorNeigborList.append(s.split(\":\")[1])\n",
" \n",
"df_sector= pd.DataFrame({\"Sector\": sectorNeigList, \"Neigborhoods\": sectorNeigborList}).merge(df_sectorPop,on='Sector' )\n",
"\n",
"print(\"There are {} Sector in {}\".format(df_sector.shape[0], bucharest_address))\n",
"df_sector"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Sector</th>\n",
" <th>SectorPopulation</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Băneasa</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Berceni</td>\n",
" <td>Sector 4</td>\n",
" <td>287,828</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Bucureștii Noi</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Centrul Civic</td>\n",
" <td>Sector 3</td>\n",
" <td>385,439</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Sector SectorPopulation\n",
"0 Aviației Sector 1 225,454\n",
"1 Băneasa Sector 1 225,454\n",
"2 Berceni Sector 4 287,828\n",
"3 Bucureștii Noi Sector 1 225,454\n",
"4 Centrul Civic Sector 3 385,439"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def getSector(row):\n",
" for i in range(df_sector.shape[0]):\n",
" if row[\"Neighborhood\"] in df_sector.iloc[i].Neigborhoods:\n",
" return pd.Series([df_sector.iloc[i].Sector, df_sector.iloc[i].Population], index = ['Sector','SectorPopulation'])\n",
"\n",
"df_neighborhood[[\"Sector\",\"SectorPopulation\"]] =df_neighborhood.apply(getSector, axis=1)\n",
"df_neighborhood.head(5)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Geographical coordinates of five neighborhoods are as below\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Sector</th>\n",
" <th>SectorPopulation</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Băneasa</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.494012</td>\n",
" <td>26.080358</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Berceni</td>\n",
" <td>Sector 4</td>\n",
" <td>287,828</td>\n",
" <td>44.386430</td>\n",
" <td>26.128490</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Bucureștii Noi</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.480413</td>\n",
" <td>26.042807</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Centrul Civic</td>\n",
" <td>Sector 3</td>\n",
" <td>385,439</td>\n",
" <td>44.434300</td>\n",
" <td>26.094660</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Sector SectorPopulation Latitude Longitude\n",
"0 Aviației Sector 1 225,454 44.485790 26.101219\n",
"1 Băneasa Sector 1 225,454 44.494012 26.080358\n",
"2 Berceni Sector 4 287,828 44.386430 26.128490\n",
"3 Bucureștii Noi Sector 1 225,454 44.480413 26.042807\n",
"4 Centrul Civic Sector 3 385,439 44.434300 26.094660"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# define a function to get coordinates\n",
"def get_latlng(neighborhood):\n",
" # initialize your variable to None\n",
" lat_lng_coords = None\n",
" # loop until you get the coordinates\n",
" while(lat_lng_coords is None):\n",
" g = geocoder.arcgis('{}, {}'.format(neighborhood,bucharest_address))\n",
" lat_lng_coords = g.latlng\n",
" return lat_lng_coords\n",
"\n",
"coords = [ get_latlng(neighborhood) for neighborhood in df_neighborhood[\"Neighborhood\"].tolist() ]\n",
"\n",
"df_coords = pd.DataFrame(coords, columns=['Latitude', 'Longitude'])\n",
"\n",
"# merge the coordinates into the original dataframe\n",
"df_neighborhood['Latitude'] = df_coords['Latitude']\n",
"df_neighborhood['Longitude'] = df_coords['Longitude']\n",
"print(\"Geographical coordinates of five neighborhoods are as below\")\n",
"df_neighborhood.head()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5IiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDQuNDM2MTQxNCwyNi4xMDI3MjAyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpvb206IDExLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcnM6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgdGlsZV9sYXllcl9kZmJkZjgwODFlZmQ0OTU5OWM1YTExNjkzYzY5OTg4YyA9IEwudGlsZUxheWVyKAogICAgICAgICAgICAgICAgJ2h0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nJywKICAgICAgICAgICAgICAgIHsKICAiYXR0cmlidXRpb24iOiBudWxsLAogICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAibWF4Wm9vbSI6IDE4LAogICJtaW5ab29tIjogMSwKICAibm9XcmFwIjogZmFsc2UsCiAgInN1YmRvbWFpbnMiOiAiYWJjIgp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWJiMzYzOWE5NjkxNDBhMmIxZDM2ZjFkMmU4OGEzZjkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40ODU3ODk1LDI2LjEwMTIxOTQ5OTk5OTk5Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yZmZkYjc5NDA4MGY0MDMzODkzMmRkZTk2NDdmMjk4MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wZjE5MDNhN2RkYTU0ZWMwYmFjM2UyNDg0ZTAxZTllNyA9ICQoJzxkaXYgaWQ9Imh0bWxfMGYxOTAzYTdkZGE1NGVjMGJhYzNlMjQ4NGUwMWU5ZTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkF2aWHIm2llaTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmZmZGI3OTQwODBmNDAzMzg5MzJkZGU5NjQ3ZjI5ODAuc2V0Q29udGVudChodG1sXzBmMTkwM2E3ZGRhNTRlYzBiYWMzZTI0ODRlMDFlOWU3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzViYjM2MzlhOTY5MTQwYTJiMWQzNmYxZDJlODhhM2Y5LmJpbmRQb3B1cChwb3B1cF8yZmZkYjc5NDA4MGY0MDMzODkzMmRkZTk2NDdmMjk4MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YjM4ZTI1NzE2NzY0YWE2ODU3YTIwODZjMGE0YzAyOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ5NDAxMjMzOTg3OTE1NiwyNi4wODAzNTg0NjUwMDUyMjZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmEyNDI4N2IyMmNiNGViODk1NmFiNGI1YmRkZWNjNTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTM2ODdhYWM3NTA3NDNiYTgzYjIyZDgwOTIzZGRjNWYgPSAkKCc8ZGl2IGlkPSJodG1sX2EzNjg3YWFjNzUwNzQzYmE4M2IyMmQ4MDkyM2RkYzVmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CxINuZWFzYTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNmEyNDI4N2IyMmNiNGViODk1NmFiNGI1YmRkZWNjNTkuc2V0Q29udGVudChodG1sX2EzNjg3YWFjNzUwNzQzYmE4M2IyMmQ4MDkyM2RkYzVmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzliMzhlMjU3MTY3NjRhYTY4NTdhMjA4NmMwYTRjMDI5LmJpbmRQb3B1cChwb3B1cF82YTI0Mjg3YjIyY2I0ZWI4OTU2YWI0YjViZGRlY2M1OSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yOWQ5NDY2M2NlMTc0MTA5YmNkZTlmNzFhZjA3MDQ2NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjM4NjQyOTk5OTQyMzExNSwyNi4xMjg0OTAwMjY2ODkxMjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDFkNWY2MmI0OTQ2NDVhYjlmMzljOTlhNTVlMzU2MmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDg0NjcxOTc2ZThmNDA0NjlmMTY4NzlkMDllZmIwMjIgPSAkKCc8ZGl2IGlkPSJodG1sX2Q4NDY3MTk3NmU4ZjQwNDY5ZjE2ODc5ZDA5ZWZiMDIyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CZXJjZW5pPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80MWQ1ZjYyYjQ5NDY0NWFiOWYzOWM5OWE1NWUzNTYyYy5zZXRDb250ZW50KGh0bWxfZDg0NjcxOTc2ZThmNDA0NjlmMTY4NzlkMDllZmIwMjIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjlkOTQ2NjNjZTE3NDEwOWJjZGU5ZjcxYWYwNzA0NjYuYmluZFBvcHVwKHBvcHVwXzQxZDVmNjJiNDk0NjQ1YWI5ZjM5Yzk5YTU1ZTM1NjJjKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZiN2YxYjhhMTJjMzQ0ZjA4M2Y1YmUzMWE2NjViNGMwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDgwNDEyOTU5NTA1NzUsMjYuMDQyODA2NTYxMjcxMjE3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRmYzE3YjRmMjZjMDRjNTliZDY5ODM3N2YzNjQ0NWRjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzlhNjhiNTBiODk1ZTRlOWU5NjQyYWZhODlmZTUwNmNkID0gJCgnPGRpdiBpZD0iaHRtbF85YTY4YjUwYjg5NWU0ZTllOTY0MmFmYTg5ZmU1MDZjZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVjdXJlyJl0aWkgTm9pPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80ZmMxN2I0ZjI2YzA0YzU5YmQ2OTgzNzdmMzY0NDVkYy5zZXRDb250ZW50KGh0bWxfOWE2OGI1MGI4OTVlNGU5ZTk2NDJhZmE4OWZlNTA2Y2QpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZmI3ZjFiOGExMmMzNDRmMDgzZjViZTMxYTY2NWI0YzAuYmluZFBvcHVwKHBvcHVwXzRmYzE3YjRmMjZjMDRjNTliZDY5ODM3N2YzNjQ0NWRjKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhkOGU4MTRiNmEyNzQzYTA5ZTUwNmIyYjQ4MTQzZTc5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDM0MzAwMDAwMDAwMDY0LDI2LjA5NDY2MDAwMDAwMDAzM10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jYTM4YzViZTg3YzM0ZjIwOTk2NjQ1ZjI1YTI2ODdkNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hOGYzMDNiZTkyOWY0ODViYTRhZTcwM2E5MTI4MmQ2MSA9ICQoJzxkaXYgaWQ9Imh0bWxfYThmMzAzYmU5MjlmNDg1YmE0YWU3MDNhOTEyODJkNjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNlbnRydWwgQ2l2aWM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2NhMzhjNWJlODdjMzRmMjA5OTY2NDVmMjVhMjY4N2Q3LnNldENvbnRlbnQoaHRtbF9hOGYzMDNiZTkyOWY0ODViYTRhZTcwM2E5MTI4MmQ2MSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84ZDhlODE0YjZhMjc0M2EwOWU1MDZiMmI0ODE0M2U3OS5iaW5kUG9wdXAocG9wdXBfY2EzOGM1YmU4N2MzNGYyMDk5NjY0NWYyNWEyNjg3ZDcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDI5ZDU1ZTk4OGRiNDlmNzliMGVkNmQxMzdhMjFmZTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40Nzk0MDA1OTY5MTM2NTYsMjYuMTY2NTM2ODA5OTQ3NDRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTdlZWVhYjkyZDNlNDEzYThiZDkyNjQ3YjI5YjVjODkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjJmYTk4OTE0MmUxNDliODkzNTY4N2U3MDljNDQxYzUgPSAkKCc8ZGl2IGlkPSJodG1sX2IyZmE5ODkxNDJlMTQ5Yjg5MzU2ODdlNzA5YzQ0MWM1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db2xlbnRpbmE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU3ZWVlYWI5MmQzZTQxM2E4YmQ5MjY0N2IyOWI1Yzg5LnNldENvbnRlbnQoaHRtbF9iMmZhOTg5MTQyZTE0OWI4OTM1Njg3ZTcwOWM0NDFjNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kMjlkNTVlOTg4ZGI0OWY3OWIwZWQ2ZDEzN2EyMWZlMC5iaW5kUG9wdXAocG9wdXBfNTdlZWVhYjkyZDNlNDEzYThiZDkyNjQ3YjI5YjVjODkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmRiMzEyYjNhMjg1NDkxNzg5NDY5MWViZTE2OTAyZDcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MzA2OTAwMDAwMDAwMywyNi4wNzM1MTAwMDAwMDAwNTZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWYzZjNkMTM3MDZkNDlkOGE1ODkxZTdhYTY5ZTU3MjkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNWM5YWJmYTc0M2YwNDA5YWFmMTRlZWM0ODYwMzNmMDggPSAkKCc8ZGl2IGlkPSJodG1sXzVjOWFiZmE3NDNmMDQwOWFhZjE0ZWVjNDg2MDMzZjA4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db3Ryb2Nlbmk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FmM2YzZDEzNzA2ZDQ5ZDhhNTg5MWU3YWE2OWU1NzI5LnNldENvbnRlbnQoaHRtbF81YzlhYmZhNzQzZjA0MDlhYWYxNGVlYzQ4NjAzM2YwOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yZGIzMTJiM2EyODU0OTE3ODk0NjkxZWJlMTY5MDJkNy5iaW5kUG9wdXAocG9wdXBfYWYzZjNkMTM3MDZkNDlkOGE1ODkxZTdhYTY5ZTU3MjkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmFkNGI3MzY3ZjNjNDFkZTg3MTU2ZTUzNzllZDNmNzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTI3NjAwMDAwMDAwNywyNi4wNDM4OTAwMDAwMDAwMzNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNGY3ODYwMzMyYTU1NDY1YTg1ZDI1NDc3ZTBhNDY1NmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjliZTkxZmFlOGIyNDhjZTg4MWRiYzk1YWQ5YzMxYjkgPSAkKCc8ZGl2IGlkPSJodG1sX2I5YmU5MWZhZThiMjQ4Y2U4ODFkYmM5NWFkOWMzMWI5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DcsOibmdhyJlpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80Zjc4NjAzMzJhNTU0NjVhODVkMjU0NzdlMGE0NjU2ZS5zZXRDb250ZW50KGh0bWxfYjliZTkxZmFlOGIyNDhjZTg4MWRiYzk1YWQ5YzMxYjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYmFkNGI3MzY3ZjNjNDFkZTg3MTU2ZTUzNzllZDNmNzcuYmluZFBvcHVwKHBvcHVwXzRmNzg2MDMzMmE1NTQ2NWE4NWQyNTQ3N2UwYTQ2NTZlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U3NmU5ODI4MmI5MjQ5NTY5MDQ4YzA4ZDRiNTkzOTJlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDE3MjM5NDAxNjU4NDksMjYuMDU3Mjg1MTgwNTE5NjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGY1M2FiOGQxY2Q3NDk1MWEzZDBjODg5Y2MxOTM5M2YgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGQzNDZmYTRlZmZjNGY0OGJjMDVmMjMwNDc1ZWU0YzIgPSAkKCc8ZGl2IGlkPSJodG1sXzBkMzQ2ZmE0ZWZmYzRmNDhiYzA1ZjIzMDQ3NWVlNGMyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5ExINtxINyb2FpYTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGY1M2FiOGQxY2Q3NDk1MWEzZDBjODg5Y2MxOTM5M2Yuc2V0Q29udGVudChodG1sXzBkMzQ2ZmE0ZWZmYzRmNDhiYzA1ZjIzMDQ3NWVlNGMyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2U3NmU5ODI4MmI5MjQ5NTY5MDQ4YzA4ZDRiNTkzOTJlLmJpbmRQb3B1cChwb3B1cF84ZjUzYWI4ZDFjZDc0OTUxYTNkMGM4ODljYzE5MzkzZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMTI4N2VmMTJmNDg0ZWY0YWRlNzQyZDI5MDU5YzAwNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMjk4MTg2MjUwODM2LDI2LjA2OTU5MzA1MDM4MDY3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80ZjU3ZDU4MWM5Mjk0MjJiOGExYTNkMzI3MzcwN2VmNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iZGIwYTkzNWQzMmI0NWJjOTM2ZTk3ZjBkNmQxYzE1MSA9ICQoJzxkaXYgaWQ9Imh0bWxfYmRiMGE5MzVkMzJiNDViYzkzNmU5N2YwZDZkMWMxNTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlYWx1bCBTcGlyaWk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRmNTdkNTgxYzkyOTQyMmI4YTFhM2QzMjczNzA3ZWY1LnNldENvbnRlbnQoaHRtbF9iZGIwYTkzNWQzMmI0NWJjOTM2ZTk3ZjBkNmQxYzE1MSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hMTI4N2VmMTJmNDg0ZWY0YWRlNzQyZDI5MDU5YzAwNC5iaW5kUG9wdXAocG9wdXBfNGY1N2Q1ODFjOTI5NDIyYjhhMWEzZDMyNzM3MDdlZjUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzk2OWY5OWU2NDk0NDVmNmEzYzc3Y2I5YzAxNWJlNWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTk2NTA5NzU3MTIwNSwyNi4wOTM3MTA3ODU5NzUyNTRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDZmM2M3NTE3NTFkNDBhM2I0ZDcwOWViNmNiMmVjNDcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWZkYTNkOGQzNDY5NGU0MGIzYTVhMDc5OWVhYjE4NmQgPSAkKCc8ZGl2IGlkPSJodG1sXzFmZGEzZDhkMzQ2OTRlNDBiM2E1YTA3OTllYWIxODZkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3JvYmFuyJtpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kNmYzYzc1MTc1MWQ0MGEzYjRkNzA5ZWI2Y2IyZWM0Ny5zZXRDb250ZW50KGh0bWxfMWZkYTNkOGQzNDY5NGU0MGIzYTVhMDc5OWVhYjE4NmQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzk2OWY5OWU2NDk0NDVmNmEzYzc3Y2I5YzAxNWJlNWIuYmluZFBvcHVwKHBvcHVwX2Q2ZjNjNzUxNzUxZDQwYTNiNGQ3MDllYjZjYjJlYzQ3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzViNThhZmUxMzEwNjRmMDNiOTI3MTAxNjZlYzk3NWU2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDIwMDkwMDAwMDAwMDcsMjYuMTM5NDQwMDAwMDAwMDM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ0MTdjNzIxZTJjMjRkNmM4MTQxMjZhOTIyOGNkMzZlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUwZjBjN2Y2N2Y0MTQ5OWQ4YjViYmFhNzBiMmUwYzUwID0gJCgnPGRpdiBpZD0iaHRtbF81MGYwYzdmNjdmNDE0OTlkOGI1YmJhYTcwYjJlMGM1MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RHJpc3RvcjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDQxN2M3MjFlMmMyNGQ2YzgxNDEyNmE5MjI4Y2QzNmUuc2V0Q29udGVudChodG1sXzUwZjBjN2Y2N2Y0MTQ5OWQ4YjViYmFhNzBiMmUwYzUwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzViNThhZmUxMzEwNjRmMDNiOTI3MTAxNjZlYzk3NWU2LmJpbmRQb3B1cChwb3B1cF80NDE3YzcyMWUyYzI0ZDZjODE0MTI2YTkyMjhjZDM2ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mN2Y2ZTY0NDY5ZTc0YzBkODU0NDAzMTAxNzMxMjAwYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMjEyMDAwMDAwMDA2NCwyNi4wMzM5NzAwMDAwMDAwNjhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODQ4ZjFlOGE5OTY4NDYyNDk4MGM4ODZjNzg3ODc3MWYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDZkNDA4ZGE4ZTAxNGVkZTg1NzNmZWVkMGNlNzIzNzEgPSAkKCc8ZGl2IGlkPSJodG1sX2Q2ZDQwOGRhOGUwMTRlZGU4NTczZmVlZDBjZTcyMzcxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EcnVtdWwgVGFiZXJlaTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODQ4ZjFlOGE5OTY4NDYyNDk4MGM4ODZjNzg3ODc3MWYuc2V0Q29udGVudChodG1sX2Q2ZDQwOGRhOGUwMTRlZGU4NTczZmVlZDBjZTcyMzcxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Y3ZjZlNjQ0NjllNzRjMGQ4NTQ0MDMxMDE3MzEyMDBiLmJpbmRQb3B1cChwb3B1cF84NDhmMWU4YTk5Njg0NjI0OTgwYzg4NmM3ODc4NzcxZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85ZGNmZTUwZjA2ZWU0ZDZiOGVjMmQyMzg2ZWEyZWQxOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyNDA5NjE1NTUzMDgyNiwyNi4xMjM2NjIzOTk3Nzc0Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iOGMxMTNjMTkxYmU0NzVjODMyYTAyMjUxOTkyNGNhYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yY2FhNTMwMmYzOGU0YTc3ODdhYWUxY2IwMDk1OTlkNCA9ICQoJzxkaXYgaWQ9Imh0bWxfMmNhYTUzMDJmMzhlNGE3Nzg3YWFlMWNiMDA5NTk5ZDQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkR1ZGXImXRpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iOGMxMTNjMTkxYmU0NzVjODMyYTAyMjUxOTkyNGNhYS5zZXRDb250ZW50KGh0bWxfMmNhYTUzMDJmMzhlNGE3Nzg3YWFlMWNiMDA5NTk5ZDQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOWRjZmU1MGYwNmVlNGQ2YjhlYzJkMjM4NmVhMmVkMTkuYmluZFBvcHVwKHBvcHVwX2I4YzExM2MxOTFiZTQ3NWM4MzJhMDIyNTE5OTI0Y2FhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I3MThhYzBlMDg1YjQ2MDA5YjViNmNjMThkY2UyMzg2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDEyODY5NTg4MDg3ODgsMjYuMDczNDI3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80OGIzNTY2ZWFhNTY0Y2I3YjdlZTQyM2NmMzkyMmE1YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zY2EyMGMwYmRkOTQ0Mjg5YjQyZGVkYzZkMGI0MTAzMCA9ICQoJzxkaXYgaWQ9Imh0bWxfM2NhMjBjMGJkZDk0NDI4OWI0MmRlZGM2ZDBiNDEwMzAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZlcmVudGFyaTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDhiMzU2NmVhYTU2NGNiN2I3ZWU0MjNjZjM5MjJhNWMuc2V0Q29udGVudChodG1sXzNjYTIwYzBiZGQ5NDQyODliNDJkZWRjNmQwYjQxMDMwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I3MThhYzBlMDg1YjQ2MDA5YjViNmNjMThkY2UyMzg2LmJpbmRQb3B1cChwb3B1cF80OGIzNTY2ZWFhNTY0Y2I3YjdlZTQyM2NmMzkyMmE1Yyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZDViZWUzNmRjM2M0NWVhOWE1N2ViZTQyMTE5ZDhiMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ3NjMwODE5MzY5ODI5LDI2LjEwMzI4ODY5OTY2ODI3Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83YmIzMjM2MThiY2I0MzZlOWNhZjJhN2I4ZGY3YWU0ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMjVjOGM0NGU1ZTU0ZDY2OTVlNmE4ODRlNzFhZDVmMSA9ICQoJzxkaXYgaWQ9Imh0bWxfYTI1YzhjNDRlNWU1NGQ2Njk1ZTZhODg0ZTcxYWQ1ZjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZsb3JlYXNjYTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2JiMzIzNjE4YmNiNDM2ZTljYWYyYTdiOGRmN2FlNGYuc2V0Q29udGVudChodG1sX2EyNWM4YzQ0ZTVlNTRkNjY5NWU2YTg4NGU3MWFkNWYxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdkNWJlZTM2ZGMzYzQ1ZWE5YTU3ZWJlNDIxMTlkOGIzLmJpbmRQb3B1cChwb3B1cF83YmIzMjM2MThiY2I0MzZlOWNhZjJhN2I4ZGY3YWU0Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yYmFiMDRmY2Q4ZDE0NzAyYmQ4YjdlNTY1MTkwY2RiNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ0OTE3NTY1MTkyNDIxLDI2LjE2NjUyMjI3ODU4NTU0M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hNjZlMTdiY2EyOTg0MjNjYjRlMmU0MTY1YzQ4YWM0OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84ZWQ5MDBjYjY5MDk0YTdlODYzYWM3MTgwMGVhNmY5MyA9ICQoJzxkaXYgaWQ9Imh0bWxfOGVkOTAwY2I2OTA5NGE3ZTg2M2FjNzE4MDBlYTZmOTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZ1bmRlbmk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E2NmUxN2JjYTI5ODQyM2NiNGUyZTQxNjVjNDhhYzQ5LnNldENvbnRlbnQoaHRtbF84ZWQ5MDBjYjY5MDk0YTdlODYzYWM3MTgwMGVhNmY5Myk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yYmFiMDRmY2Q4ZDE0NzAyYmQ4YjdlNTY1MTkwY2RiNC5iaW5kUG9wdXAocG9wdXBfYTY2ZTE3YmNhMjk4NDIzY2I0ZTJlNDE2NWM0OGFjNDkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTJjYzgxOGRlZjBkNDNmZTk4NTFlODMxODZjYTlkN2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MTgzNjAwMDAwMDAwNjQsMjYuMDU4NjAwMDAwMDAwMDddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmM2MTExMTQ3ZDgzNDkyNzk4NTdkM2ZjOGZmOTg0NTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2UzMTY5NjkzYTg4NGUwOGFhMmE2NGM5MTNjMDFkZWIgPSAkKCc8ZGl2IGlkPSJodG1sX2NlMzE2OTY5M2E4ODRlMDhhYTJhNjRjOTEzYzAxZGViIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HaGVuY2VhPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iYzYxMTExNDdkODM0OTI3OTg1N2QzZmM4ZmY5ODQ1OS5zZXRDb250ZW50KGh0bWxfY2UzMTY5NjkzYTg4NGUwOGFhMmE2NGM5MTNjMDFkZWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTJjYzgxOGRlZjBkNDNmZTk4NTFlODMxODZjYTlkN2EuYmluZFBvcHVwKHBvcHVwX2JjNjExMTE0N2Q4MzQ5Mjc5ODU3ZDNmYzhmZjk4NDU5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE0NjAzMmY0NmZlNTRmNWZhNTRhMzZkZjgyYWE1OTk4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDcwMDgzMzU5ODA0NTcsMjYuMDAyNTEyNDU2MzkxNzAzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E3MDdmYThhYjFhODQ5ZTE5MWRhNTM4MTA4ODA5MjIzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U3YjEwNGQxNGYxNzQ2ZWZhYWJiMzhjOTBhYzBjYjc2ID0gJCgnPGRpdiBpZD0iaHRtbF9lN2IxMDRkMTRmMTc0NmVmYWFiYjM4YzkwYWMwY2I3NiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2l1bGXImXRpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNzA3ZmE4YWIxYTg0OWUxOTFkYTUzODEwODgwOTIyMy5zZXRDb250ZW50KGh0bWxfZTdiMTA0ZDE0ZjE3NDZlZmFhYmIzOGM5MGFjMGNiNzYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTQ2MDMyZjQ2ZmU1NGY1ZmE1NGEzNmRmODJhYTU5OTguYmluZFBvcHVwKHBvcHVwX2E3MDdmYThhYjFhODQ5ZTE5MWRhNTM4MTA4ODA5MjIzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNlNzkyY2IzOWYyMzRiOWI4YjJkZDAxNTFkMDU0Y2NhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQ3NzUwMDAwMDAwMDQsMjYuMDc1MzkwMDAwMDAwMDI3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I3NzI1NzNhNDQzNDRmYWViNDEwODdkNDM2ZmIzNDg5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2UzZWY1NjYxYTg3MjRlYjU4MDZkMzU0ZmU4ODE3OWM2ID0gJCgnPGRpdiBpZD0iaHRtbF9lM2VmNTY2MWE4NzI0ZWI1ODA2ZDM1NGZlODgxNzljNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3JpdmnIm2E8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I3NzI1NzNhNDQzNDRmYWViNDEwODdkNDM2ZmIzNDg5LnNldENvbnRlbnQoaHRtbF9lM2VmNTY2MWE4NzI0ZWI1ODA2ZDM1NGZlODgxNzljNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zZTc5MmNiMzlmMjM0YjliOGIyZGQwMTUxZDA1NGNjYS5iaW5kUG9wdXAocG9wdXBfYjc3MjU3M2E0NDM0NGZhZWI0MTA4N2Q0MzZmYjM0ODkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzZjODA1NTRmNDUxNDM2MjhkMjdhNWY3ODRlYmNlZTggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NDAzNzUzODY5NjQwNCwyNi4xMzQ0NTIwMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNjU1NWI5Y2MyYjA0OGIyYTlhNGY4NzgzMmJjMTQ2ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80YjgzYzU1OGQyODc0NzUyODAxOGU0MWVmYjljMjg2MSA9ICQoJzxkaXYgaWQ9Imh0bWxfNGI4M2M1NThkMjg3NDc1MjgwMThlNDFlZmI5YzI4NjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPklhbmN1bHVpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kNjU1NWI5Y2MyYjA0OGIyYTlhNGY4NzgzMmJjMTQ2Zi5zZXRDb250ZW50KGh0bWxfNGI4M2M1NThkMjg3NDc1MjgwMThlNDFlZmI5YzI4NjEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMzZjODA1NTRmNDUxNDM2MjhkMjdhNWY3ODRlYmNlZTguYmluZFBvcHVwKHBvcHVwX2Q2NTU1YjljYzJiMDQ4YjJhOWE0Zjg3ODMyYmMxNDZmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RiYTNhODFmY2UyYjQ5NWQ4ZDdlMGFhZDg3OWQ2ZDAwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDMyMTU1MzQzOTUxMywyNi4xMDQwNTY2MjM0MzM5NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83Yzk1NThjNGVlM2E0M2FjYWI4MzJmZDI3MDc0OGZhNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85NTJiZDc0Zjg2YzE0NTQwOGIzZTY3MGM4ZjliOTZhYiA9ICQoJzxkaXYgaWQ9Imh0bWxfOTUyYmQ3NGY4NmMxNDU0MDhiM2U2NzBjOGY5Yjk2YWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxpcHNjYW5pPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83Yzk1NThjNGVlM2E0M2FjYWI4MzJmZDI3MDc0OGZhNy5zZXRDb250ZW50KGh0bWxfOTUyYmQ3NGY4NmMxNDU0MDhiM2U2NzBjOGY5Yjk2YWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZGJhM2E4MWZjZTJiNDk1ZDhkN2UwYWFkODc5ZDZkMDAuYmluZFBvcHVwKHBvcHVwXzdjOTU1OGM0ZWUzYTQzYWNhYjgzMmZkMjcwNzQ4ZmE3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzU4ZWJjZTA0NzMzNjRmMjc5MDc1ZjZjNzg4YTVmZmIyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDM0MjkwMDAwMDAwMDMsMjYuMTAyOTgwMDAwMDAwMDZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2FhYTY1ZjIyOTJjNDlmMDhiNjExMmI1YTgxYjlmOTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYzc1YTZjOTM1ZThiNDM1NGI4Y2U4NmI1NTE5MTI3NDggPSAkKCc8ZGl2IGlkPSJodG1sX2M3NWE2YzkzNWU4YjQzNTRiOGNlODZiNTUxOTEyNzQ4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NaWxpdGFyaTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2FhYTY1ZjIyOTJjNDlmMDhiNjExMmI1YTgxYjlmOTAuc2V0Q29udGVudChodG1sX2M3NWE2YzkzNWU4YjQzNTRiOGNlODZiNTUxOTEyNzQ4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU4ZWJjZTA0NzMzNjRmMjc5MDc1ZjZjNzg4YTVmZmIyLmJpbmRQb3B1cChwb3B1cF9jYWFhNjVmMjI5MmM0OWYwOGI2MTEyYjVhODFiOWY5MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yYzlkMzE1ZDA3OTc0NjU1YTA4OTMxODI3NzJhZWE2YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQxMjQwMzUsMjYuMTIzNDAyMjUwMDAwMDE2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2EyMGE2OWE4NTllYjQ0YzdhYmU4Mjg2OTIxMDgxZmU2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2FlMTdmNTc5Mjg5YTRiNDM5YTQ4MDhiZTYwOWVjYWIzID0gJCgnPGRpdiBpZD0iaHRtbF9hZTE3ZjU3OTI4OWE0YjQzOWE0ODA4YmU2MDllY2FiMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TW/ImWlsb3I8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2EyMGE2OWE4NTllYjQ0YzdhYmU4Mjg2OTIxMDgxZmU2LnNldENvbnRlbnQoaHRtbF9hZTE3ZjU3OTI4OWE0YjQzOWE0ODA4YmU2MDllY2FiMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yYzlkMzE1ZDA3OTc0NjU1YTA4OTMxODI3NzJhZWE2Yi5iaW5kUG9wdXAocG9wdXBfYTIwYTY5YTg1OWViNDRjN2FiZTgyODY5MjEwODFmZTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzkzNTYxZjk4MDY2NGUzM2E4ZmFiZTEzM2EzODRiZWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTE0NzAwMDAwMDAwMywyNi4xMjY0NzAwMDAwMDAwNF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMjE0ODA0YzJjMmE0MTUzOGM3ZmFmNzVlZTllM2IzOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81YWQ0MTgxNTdkZWY0ZWJkYWM1YTM5ZjY4YTdmM2U4MyA9ICQoJzxkaXYgaWQ9Imh0bWxfNWFkNDE4MTU3ZGVmNGViZGFjNWEzOWY2OGE3ZjNlODMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk9ib3I8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2EyMTQ4MDRjMmMyYTQxNTM4YzdmYWY3NWVlOWUzYjM5LnNldENvbnRlbnQoaHRtbF81YWQ0MTgxNTdkZWY0ZWJkYWM1YTM5ZjY4YTdmM2U4Myk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jOTM1NjFmOTgwNjY0ZTMzYThmYWJlMTMzYTM4NGJlYi5iaW5kUG9wdXAocG9wdXBfYTIxNDgwNGMyYzJhNDE1MzhjN2ZhZjc1ZWU5ZTNiMzkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjgxNGU1OTgzNjZmNDk4N2E3ZmVkYWJlZmUwMzQyMGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC41MjkxMzYwMTUxNDQ5MzUsMjYuMDQ3NDQwNTczMDM1Njk3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg2YzZiZmEwNGFkYjQ4OTBhNjQ2NDNhY2IwZWFhNjQ3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcxYTY3YTczNDcyMjRkYzBiYjBjODgzNmVlNWZmNGJmID0gJCgnPGRpdiBpZD0iaHRtbF83MWE2N2E3MzQ3MjI0ZGMwYmIwYzg4MzZlZTVmZjRiZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+T2TEg2k8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzg2YzZiZmEwNGFkYjQ4OTBhNjQ2NDNhY2IwZWFhNjQ3LnNldENvbnRlbnQoaHRtbF83MWE2N2E3MzQ3MjI0ZGMwYmIwYzg4MzZlZTVmZjRiZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yODE0ZTU5ODM2NmY0OTg3YTdmZWRhYmVmZTAzNDIwZC5iaW5kUG9wdXAocG9wdXBfODZjNmJmYTA0YWRiNDg5MGE2NDY0M2FjYjBlYWE2NDcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDg5YzUyMTIwYjRkNDc1OTlhMDA2MTE3N2VjMTQ2MzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC4zOTA0NTg4NDUzMTI1LDI2LjEyOTEwMTQyMjYzMTgxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzE2NWVkM2U2OTlhOTQ2ZWQ4YmUyZjE2ODZiNjAwMGM2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM1YmJhMDU5MzYwNTQwNjk5ODkwYTU0ZGYxMzQyZjRhID0gJCgnPGRpdiBpZD0iaHRtbF8zNWJiYTA1OTM2MDU0MDY5OTg5MGE1NGRmMTM0MmY0YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+T2x0ZW5pyJtlaTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTY1ZWQzZTY5OWE5NDZlZDhiZTJmMTY4NmI2MDAwYzYuc2V0Q29udGVudChodG1sXzM1YmJhMDU5MzYwNTQwNjk5ODkwYTU0ZGYxMzQyZjRhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Q4OWM1MjEyMGI0ZDQ3NTk5YTAwNjExNzdlYzE0NjM3LmJpbmRQb3B1cChwb3B1cF8xNjVlZDNlNjk5YTk0NmVkOGJlMmYxNjg2YjYwMDBjNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84NjQ0YzE5MThjNzA0MzY0ODVlOWMzOTM0YWZlNTZmNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ0MTUyODI3MTcyODY2NCwyNi4xOTQyNDg5MDIxMDA2NjRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWQ4ZDE4MDNkMzc1NGZlNWE0NTg2YWVjNjhkYWMzNjggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjMyZTkyYmRlOGMzNDIyNGFjZTkxZWFiODc5YTgwOWIgPSAkKCc8ZGl2IGlkPSJodG1sX2IzMmU5MmJkZThjMzQyMjRhY2U5MWVhYjg3OWE4MDliIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYW50ZWxpbW9uPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hZDhkMTgwM2QzNzU0ZmU1YTQ1ODZhZWM2OGRhYzM2OC5zZXRDb250ZW50KGh0bWxfYjMyZTkyYmRlOGMzNDIyNGFjZTkxZWFiODc5YTgwOWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODY0NGMxOTE4YzcwNDM2NDg1ZTljMzkzNGFmZTU2ZjUuYmluZFBvcHVwKHBvcHVwX2FkOGQxODAzZDM3NTRmZTVhNDU4NmFlYzY4ZGFjMzY4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U1NTkxNWIzZmEzZDQ5NDZhNmU2YmE0MTk4MWQyZmNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDg3MTYwMTM2NTAyNDMsMjYuMTE0Njc3MDg5NTc2NjVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2FlNjAwNDljMDRjNGVmYjllMzRhMGY3YzAzMDJjNzEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODVhMWMwY2QzNGNjNDRjOWE0MmQ3YmRmZmUzZWQzNTkgPSAkKCc8ZGl2IGlkPSJodG1sXzg1YTFjMGNkMzRjYzQ0YzlhNDJkN2JkZmZlM2VkMzU5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QaXBlcmE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzdhZTYwMDQ5YzA0YzRlZmI5ZTM0YTBmN2MwMzAyYzcxLnNldENvbnRlbnQoaHRtbF84NWExYzBjZDM0Y2M0NGM5YTQyZDdiZGZmZTNlZDM1OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lNTU5MTViM2ZhM2Q0OTQ2YTZlNmJhNDE5ODFkMmZjZS5iaW5kUG9wdXAocG9wdXBfN2FlNjAwNDljMDRjNGVmYjllMzRhMGY3YzAzMDJjNzEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzRiMjgzYzM1OTUwNDMxOGJjY2E5MjU5NjFiZmYwZmEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40Njk3MTA4NTYzMDI4NTQsMjYuMDkyODY2NTAwNzM1MDA2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U3MTNiOTNlMmI5NTQzYTFiNTRiNTUwNzgyZDEwM2IwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzViZDMzMmY1NGI3MjQ3Y2Y4NGYyMmRiOWQxZGM3YTA5ID0gJCgnPGRpdiBpZD0iaHRtbF81YmQzMzJmNTRiNzI0N2NmODRmMjJkYjlkMWRjN2EwOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UHJpbcSDdmVyaWk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U3MTNiOTNlMmI5NTQzYTFiNTRiNTUwNzgyZDEwM2IwLnNldENvbnRlbnQoaHRtbF81YmQzMzJmNTRiNzI0N2NmODRmMjJkYjlkMWRjN2EwOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jNGIyODNjMzU5NTA0MzE4YmNjYTkyNTk2MWJmZjBmYS5iaW5kUG9wdXAocG9wdXBfZTcxM2I5M2UyYjk1NDNhMWI1NGI1NTA3ODJkMTAzYjApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDE3NzQyY2JmZWYyNDBhMzkwY2ZkMDk3NzU2NjAzNTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MjM5MzI1MDAwMDAwMTQsMjYuMDY3ODU4NzQ5OTk5OTkyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk0NDBlZTM3NjcyNTQyY2ZhNzQ4OWE4MDA3ZGIzMTY4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2I0ZTNiM2I5ZmZkMTRkZThiNjY0NmM4ZDQ4ZWY5ZDliID0gJCgnPGRpdiBpZD0iaHRtbF9iNGUzYjNiOWZmZDE0ZGU4YjY2NDZjOGQ0OGVmOWQ5YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UHJvZ3Jlc3VsPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85NDQwZWUzNzY3MjU0MmNmYTc0ODlhODAwN2RiMzE2OC5zZXRDb250ZW50KGh0bWxfYjRlM2IzYjlmZmQxNGRlOGI2NjQ2YzhkNDhlZjlkOWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDE3NzQyY2JmZWYyNDBhMzkwY2ZkMDk3NzU2NjAzNTkuYmluZFBvcHVwKHBvcHVwXzk0NDBlZTM3NjcyNTQyY2ZhNzQ4OWE4MDA3ZGIzMTY4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q3YjcwNzlkNzBjZDQ5ZWVhMDU5MjU5YzIwMTdhM2FiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDA4NDgwMDAwMDAwMDU0LDI2LjA2NzMzMDAwMDAwMDAyN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNmJlYzNmN2EyMTM0NDBjODUyYjRhNzgzMzA2N2IyOCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MzAzNjQ1MDUwMDA0ZjMxODU4ZGM2ZDBiNjcxNmFjMCA9ICQoJzxkaXYgaWQ9Imh0bWxfNTMwMzY0NTA1MDAwNGYzMTg1OGRjNmQwYjY3MTZhYzAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJhaG92YTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDZiZWMzZjdhMjEzNDQwYzg1MmI0YTc4MzMwNjdiMjguc2V0Q29udGVudChodG1sXzUzMDM2NDUwNTAwMDRmMzE4NThkYzZkMGI2NzE2YWMwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Q3YjcwNzlkNzBjZDQ5ZWVhMDU5MjU5YzIwMTdhM2FiLmJpbmRQb3B1cChwb3B1cF9kNmJlYzNmN2EyMTM0NDBjODUyYjRhNzgzMzA2N2IyOCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83YjgyY2IyODc3NDU0ODNlOTUyYjg3YzJkNzE3NjQyNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ0NjYxNjk5OTk5OTk5LDI2LjA1OTQ3MDc0OTk5OTk5Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hNjlhMDllZmNjMDk0NjM5YTFjODhhNmM2YWU1Y2YyZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iM2ZmMThhZWM5NTM0ZjNjYjM0YTAxZGFkOTRjMjI0YiA9ICQoJzxkaXYgaWQ9Imh0bWxfYjNmZjE4YWVjOTUzNGYzY2IzNGEwMWRhZDk0YzIyNGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJlZ2llPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNjlhMDllZmNjMDk0NjM5YTFjODhhNmM2YWU1Y2YyZC5zZXRDb250ZW50KGh0bWxfYjNmZjE4YWVjOTUzNGYzY2IzNGEwMWRhZDk0YzIyNGIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfN2I4MmNiMjg3NzQ1NDgzZTk1MmI4N2MyZDcxNzY0MjYuYmluZFBvcHVwKHBvcHVwX2E2OWEwOWVmY2MwOTQ2MzlhMWM4OGE2YzZhZTVjZjJkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ2ZDQ0Y2MwMTE2ZDQ5ZDVhZjI5NzUzOWQzYTM5OGY4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQxNjA4NDk5OTk5OTk0LDI1Ljk4MjM3ODk5OTk5OTk5NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iZTIyZGU1YjM1ZjQ0OTk5OWY2MjY3NDIyMzAzMDYyOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80OTYxNmJhYWMzMzY0MjVkYjExYzY4NDE1ZDZlYWU4ZCA9ICQoJzxkaXYgaWQ9Imh0bWxfNDk2MTZiYWFjMzM2NDI1ZGIxMWM2ODQxNWQ2ZWFlOGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRpbmVyZXR1bHVpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iZTIyZGU1YjM1ZjQ0OTk5OWY2MjY3NDIyMzAzMDYyOS5zZXRDb250ZW50KGh0bWxfNDk2MTZiYWFjMzM2NDI1ZGIxMWM2ODQxNWQ2ZWFlOGQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDZkNDRjYzAxMTZkNDlkNWFmMjk3NTM5ZDNhMzk4ZjguYmluZFBvcHVwKHBvcHVwX2JlMjJkZTViMzVmNDQ5OTk5ZjYyNjc0MjIzMDMwNjI5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YzZjIyOGFkNjkxZDRlN2VhZTdmOTNhNTc3M2E2ODUxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDI0OTk3Njc5NzgzMDQsMjYuMDgzMzMxMDI1OTgxMTY3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzk4MzA4N2JmMDE4YjRkNDc4OTYzMzA4NTYyYjA1MzI5KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ0OGNkNmJhYmI5YzQ3NWM4NjllNmNiZTRiNDE1OGYzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2JiMmJhMjE4MTQ4MTQyZDRiZmM4MDFkNjdmZTdiOWE1ID0gJCgnPGRpdiBpZD0iaHRtbF9iYjJiYTIxODE0ODE0MmQ0YmZjODAxZDY3ZmU3YjlhNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTMgU2VwdGVtYnJpZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDQ4Y2Q2YmFiYjljNDc1Yzg2OWU2Y2JlNGI0MTU4ZjMuc2V0Q29udGVudChodG1sX2JiMmJhMjE4MTQ4MTQyZDRiZmM4MDFkNjdmZTdiOWE1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YzZjIyOGFkNjkxZDRlN2VhZTdmOTNhNTc3M2E2ODUxLmJpbmRQb3B1cChwb3B1cF80NDhjZDZiYWJiOWM0NzVjODY5ZTZjYmU0YjQxNThmMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMTE2NGQ0MDJkNjE0YTQ1OTcwYzYyNDZiMjc4MmQ1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjM5MDIxMDAwMDAwMDAyNSwyNi4wOTI0NTAwMDAwMDAwNDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWEyOWFlYTVhMGZlNDNhYmI2YjE3NzlmMmRkNDNkYjIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWJmMDc2OWU5NmE4NGVjNTg4MzhmNjZjNzFkMTM1Y2EgPSAkKCc8ZGl2IGlkPSJodG1sXzFiZjA3NjllOTZhODRlYzU4ODM4ZjY2YzcxZDEzNWNhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HaXVyZ2l1bHVpPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hYTI5YWVhNWEwZmU0M2FiYjZiMTc3OWYyZGQ0M2RiMi5zZXRDb250ZW50KGh0bWxfMWJmMDc2OWU5NmE4NGVjNTg4MzhmNjZjNzFkMTM1Y2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzExNjRkNDAyZDYxNGE0NTk3MGM2MjQ2YjI3ODJkNTYuYmluZFBvcHVwKHBvcHVwX2FhMjlhZWE1YTBmZTQzYWJiNmIxNzc5ZjJkZDQzZGIyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzVhYmMxYjdiMjQ0YzRhNTk5OWIxZDE5YTY1YzFmNTYyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDM0MjkwMDAwMDAwMDMsMjYuMTAyOTgwMDAwMDAwMDZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzE1Nzk1MDVhOGUxNDM4ZDhhZmVmYjI5MTA3YjU3NDAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjRmMThlNmMxY2U1NDNjY2FlMTU1ZDhlNjkwNDFiYzMgPSAkKCc8ZGl2IGlkPSJodG1sX2Y0ZjE4ZTZjMWNlNTQzY2NhZTE1NWQ4ZTY5MDQxYmMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UZWk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzMxNTc5NTA1YThlMTQzOGQ4YWZlZmIyOTEwN2I1NzQwLnNldENvbnRlbnQoaHRtbF9mNGYxOGU2YzFjZTU0M2NjYWUxNTVkOGU2OTA0MWJjMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81YWJjMWI3YjI0NGM0YTU5OTliMWQxOWE2NWMxZjU2Mi5iaW5kUG9wdXAocG9wdXBfMzE1Nzk1MDVhOGUxNDM4ZDhhZmVmYjI5MTA3YjU3NDApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjFkNTU2Y2M1MjZjNDAyMjg3MjA3YjA3ZjBmOTc3YTYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTY4NTAwMDAwMDAwMywyNi4xMDA2NDAwMDAwMDAwNTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDdiNWJmN2ZiYjA0NDhhMDllZjllMDIzODk5Y2NiMjIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmNhMDFkNjY0ODgyNGJlM2IxMjYyN2Q2YmU4ZmFmNTkgPSAkKCc8ZGl2IGlkPSJodG1sX2JjYTAxZDY2NDg4MjRiZTNiMTI2MjdkNmJlOGZhZjU5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaXRhbjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDdiNWJmN2ZiYjA0NDhhMDllZjllMDIzODk5Y2NiMjIuc2V0Q29udGVudChodG1sX2JjYTAxZDY2NDg4MjRiZTNiMTI2MjdkNmJlOGZhZjU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzYxZDU1NmNjNTI2YzQwMjI4NzIwN2IwN2YwZjk3N2E2LmJpbmRQb3B1cChwb3B1cF9kN2I1YmY3ZmJiMDQ0OGEwOWVmOWUwMjM4OTljY2IyMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83N2M2MTZhNjE5ZWQ0OGFhYWVmNGQxZWY5MDdkMGRjOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQxNTUzMDAwMDAwMDA1LDI2LjExMzU0MDAwMDAwMDA1N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF85ODMwODdiZjAxOGI0ZDQ3ODk2MzMwODU2MmIwNTMyOSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMDY4MDQyZTcyMzQ0ZTRkOWQyMmFlNTU3NWIwZmVmMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMDZjOTgzNmJmNDg0YjA1YjFkYzU5Y2QxODI1ZGZhZiA9ICQoJzxkaXYgaWQ9Imh0bWxfYTA2Yzk4MzZiZjQ4NGIwNWIxZGM1OWNkMTgyNWRmYWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlbEg2PEg3JlyJl0aTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTA2ODA0MmU3MjM0NGU0ZDlkMjJhZTU1NzViMGZlZjIuc2V0Q29udGVudChodG1sX2EwNmM5ODM2YmY0ODRiMDViMWRjNTljZDE4MjVkZmFmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzc3YzYxNmE2MTllZDQ4YWFhZWY0ZDFlZjkwN2QwZGM5LmJpbmRQb3B1cChwb3B1cF9hMDY4MDQyZTcyMzQ0ZTRkOWQyMmFlNTU3NWIwZmVmMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNjRiMzFlMWJmY2Q0YzU4ODYwNTVjZjAyZDhhMjU1YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMjczNTA0NzQ4MTk4NiwyNi4xMjQ0ODg0MjI5OTgzNThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfOTgzMDg3YmYwMThiNGQ0Nzg5NjMzMDg1NjJiMDUzMjkpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDFmMTllMzUzZjNmNDkxNDhlNWViYzkxOTliMzdjODIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmU0NzVjNTgyOGI1NDMxY2E1M2E1ZjBmNDc0OTI4YWQgPSAkKCc8ZGl2IGlkPSJodG1sXzJlNDc1YzU4MjhiNTQzMWNhNTNhNWYwZjQ3NDkyOGFkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5WaXRhbjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDFmMTllMzUzZjNmNDkxNDhlNWViYzkxOTliMzdjODIuc2V0Q29udGVudChodG1sXzJlNDc1YzU4MjhiNTQzMWNhNTNhNWYwZjQ3NDkyOGFkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzE2NGIzMWUxYmZjZDRjNTg4NjA1NWNmMDJkOGEyNTVhLmJpbmRQb3B1cChwb3B1cF80MWYxOWUzNTNmM2Y0OTE0OGU1ZWJjOTE5OWIzN2M4Mik7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+ onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7fc585987cc0>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#create map of Bucharest neighborhoods using latitude and longitude values\n",
"map_bucharest= folium.Map(location=[latitude, longitude], zoom_start=11)\n",
"\n",
"# add markers to map\n",
"for lat, lng, neighborhood in zip(df_neighborhood['Latitude'], df_neighborhood['Longitude'], df_neighborhood['Neighborhood']):\n",
" label = '{}'.format(neighborhood)\n",
" label = folium.Popup(label, parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lng],\n",
" radius=5,\n",
" popup=label,\n",
" color='blue',\n",
" fill=True,\n",
" fill_color='#3186cc',\n",
" fill_opacity=0.7,\n",
" parse_html=False).add_to(map_bucharest) \n",
" \n",
"map_bucharest"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# @hidden_cell\n",
" CLIENT_ID=\"Q5SAY0XAYHJ2KXJ3AIRKQJ2IPWSWFCPR5FOA5OFWCBE2DEUF\"\n",
" CLIENT_SECRET=\"HK1XAI1VDMPCZWIXOUIUPVJ0ECGRR1OJTE0MEKZIBVRH5PGW\"\n",
" VERSION=\"20180605\"\n"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 224 unique venue categories. Some of them are as below:\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>VenueName</th>\n",
" <th>VenueId</th>\n",
" <th>VenueLatitude</th>\n",
" <th>VenueLongitude</th>\n",
" <th>VenueDistance</th>\n",
" <th>VenueCategory</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>44.48579</td>\n",
" <td>26.101219</td>\n",
" <td>ibis Styles Bucharest Erbas</td>\n",
" <td>5bbb782175dcb7002cc15ee7</td>\n",
" <td>44.483963</td>\n",
" <td>26.097134</td>\n",
" <td>382</td>\n",
" <td>Hotel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Aviației</td>\n",
" <td>44.48579</td>\n",
" <td>26.101219</td>\n",
" <td>LIDL</td>\n",
" <td>583956246d349d0574eb02ac</td>\n",
" <td>44.488396</td>\n",
" <td>26.094375</td>\n",
" <td>616</td>\n",
" <td>Supermarket</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Aviației</td>\n",
" <td>44.48579</td>\n",
" <td>26.101219</td>\n",
" <td>Mega Image Concept Store</td>\n",
" <td>56348b62498e53f51a0a4e0e</td>\n",
" <td>44.479783</td>\n",
" <td>26.102568</td>\n",
" <td>677</td>\n",
" <td>Supermarket</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Aviației</td>\n",
" <td>44.48579</td>\n",
" <td>26.101219</td>\n",
" <td>Starbucks</td>\n",
" <td>525fd077498eed1c5a52c1d6</td>\n",
" <td>44.478522</td>\n",
" <td>26.102503</td>\n",
" <td>815</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Aviației</td>\n",
" <td>44.48579</td>\n",
" <td>26.101219</td>\n",
" <td>Flying Pig</td>\n",
" <td>58a2fc95d0bb3e516a2363b7</td>\n",
" <td>44.479454</td>\n",
" <td>26.102837</td>\n",
" <td>716</td>\n",
" <td>Burger Joint</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Latitude Longitude VenueName \\\n",
"0 Aviației 44.48579 26.101219 ibis Styles Bucharest Erbas \n",
"1 Aviației 44.48579 26.101219 LIDL \n",
"2 Aviației 44.48579 26.101219 Mega Image Concept Store \n",
"3 Aviației 44.48579 26.101219 Starbucks \n",
"4 Aviației 44.48579 26.101219 Flying Pig \n",
"\n",
" VenueId VenueLatitude VenueLongitude VenueDistance \\\n",
"0 5bbb782175dcb7002cc15ee7 44.483963 26.097134 382 \n",
"1 583956246d349d0574eb02ac 44.488396 26.094375 616 \n",
"2 56348b62498e53f51a0a4e0e 44.479783 26.102568 677 \n",
"3 525fd077498eed1c5a52c1d6 44.478522 26.102503 815 \n",
"4 58a2fc95d0bb3e516a2363b7 44.479454 26.102837 716 \n",
"\n",
" VenueCategory \n",
"0 Hotel \n",
"1 Supermarket \n",
"2 Supermarket \n",
"3 Coffee Shop \n",
"4 Burger Joint "
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"LIMIT = 100\n",
"\n",
"def getNeighborhoodVenues( latitude, longitude,neighborhood, radius=1000 ):\n",
" venues = []\n",
" for lat, long, neighborhood in zip(latitude, longitude ,neighborhood):\n",
"\n",
" # create the API request URL\n",
" url = \"https://api.foursquare.com/v2/venues/explore?client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}\".format(\n",
" CLIENT_ID,\n",
" CLIENT_SECRET,\n",
" VERSION,\n",
" lat,\n",
" long,\n",
" radius, \n",
" LIMIT)\n",
"\n",
" # make the GET request\n",
" results = requests.get(url).json()[\"response\"]['groups'][0]['items']\n",
"\n",
" # return only relevant information for each nearby venue\n",
" for venue in results:\n",
" venues.append((\n",
" neighborhood,\n",
" lat, \n",
" long, \n",
" venue['venue']['name'], \n",
" venue['venue']['id'], \n",
" venue['venue']['location']['lat'], \n",
" venue['venue']['location']['lng'], \n",
" venue['venue']['location']['distance'], \n",
" venue['venue']['categories'][0]['name']))\n",
" \n",
" # convert the venues list into a DataFrame\n",
" venues = pd.DataFrame(venues)\n",
" # define the column names\n",
" venues.columns = ['Neighborhood', 'Latitude', 'Longitude', 'VenueName', 'VenueId', 'VenueLatitude', 'VenueLongitude','VenueDistance','VenueCategory']\n",
" \n",
" return venues \n",
"\n",
"neighborhood_venues = getNeighborhoodVenues (df_neighborhood['Latitude'], df_neighborhood['Longitude'], df_neighborhood['Neighborhood'] )\n",
"\n",
"print('There are {} unique venue categories. Some of them are as below:'.format(len(neighborhood_venues['VenueCategory'].unique())))\n",
"neighborhood_venues.head()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Top 10 distinct venue counts are as below\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Count</th>\n",
" </tr>\n",
" <tr>\n",
" <th>VenueCategory</th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Café</th>\n",
" <td>69</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Restaurant</th>\n",
" <td>65</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Coffee Shop</th>\n",
" <td>59</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Italian Restaurant</th>\n",
" <td>56</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pizza Place</th>\n",
" <td>52</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Supermarket</th>\n",
" <td>52</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Gym</th>\n",
" <td>39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hotel</th>\n",
" <td>39</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Romanian Restaurant</th>\n",
" <td>38</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Gym / Fitness Center</th>\n",
" <td>36</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Burger Joint</th>\n",
" <td>34</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Park</th>\n",
" <td>32</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Clothing Store</th>\n",
" <td>30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bakery</th>\n",
" <td>27</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pub</th>\n",
" <td>26</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Dessert Shop</th>\n",
" <td>24</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Lounge</th>\n",
" <td>24</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bistro</th>\n",
" <td>22</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Fried Chicken Joint</th>\n",
" <td>19</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Eastern European Restaurant</th>\n",
" <td>19</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bus Station</th>\n",
" <td>17</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pharmacy</th>\n",
" <td>17</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Plaza</th>\n",
" <td>16</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Grocery Store</th>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Cosmetics Shop</th>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Sandwich Place</th>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Farmers Market</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Department Store</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Electronics Store</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bar</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Fast Food Restaurant</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Chinese Restaurant</th>\n",
" <td>13</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Middle Eastern Restaurant</th>\n",
" <td>12</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Salon / Barbershop</th>\n",
" <td>12</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Cupcake Shop</th>\n",
" <td>11</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Doner Restaurant</th>\n",
" <td>11</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Furniture / Home Store</th>\n",
" <td>11</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Lebanese Restaurant</th>\n",
" <td>11</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bookstore</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Steakhouse</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Sushi Restaurant</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Ice Cream Shop</th>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pool</th>\n",
" <td>9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Turkish Restaurant</th>\n",
" <td>9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nightclub</th>\n",
" <td>9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mediterranean Restaurant</th>\n",
" <td>9</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Spa</th>\n",
" <td>8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Beer Garden</th>\n",
" <td>8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hostel</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Tea Room</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Wine Bar</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mobile Phone Shop</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Soccer Field</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Shopping Mall</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Theater</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Seafood Restaurant</th>\n",
" <td>7</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Greek Restaurant</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Casino</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Health &amp; Beauty Service</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Light Rail Station</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Cocktail Bar</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Sporting Goods Shop</th>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Snack Place</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Roof Deck</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bagel Shop</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Gastropub</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Food &amp; Drink Shop</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Salad Place</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Multiplex</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Garden</th>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>French Restaurant</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>American Restaurant</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diner</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Asian Restaurant</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Vietnamese Restaurant</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Tram Station</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Metro Station</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>History Museum</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Modern European Restaurant</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>German Restaurant</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Market</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Accessories Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hardware Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Historic Site</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Women's Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Shoe Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Chocolate Shop</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Art Gallery</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Art Museum</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Arts &amp; Crafts Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Wine Shop</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Toy / Game Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Tennis Court</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Beer Bar</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Spanish Restaurant</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Palace</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Dance Studio</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Concert Hall</th>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Convenience Store</th>\n",
" <td>3</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Count\n",
"VenueCategory \n",
"Café 69\n",
"Restaurant 65\n",
"Coffee Shop 59\n",
"Italian Restaurant 56\n",
"Pizza Place 52\n",
"Supermarket 52\n",
"Gym 39\n",
"Hotel 39\n",
"Romanian Restaurant 38\n",
"Gym / Fitness Center 36\n",
"Burger Joint 34\n",
"Park 32\n",
"Clothing Store 30\n",
"Bakery 27\n",
"Pub 26\n",
"Dessert Shop 24\n",
"Lounge 24\n",
"Bistro 22\n",
"Fried Chicken Joint 19\n",
"Eastern European Restaurant 19\n",
"Bus Station 17\n",
"Pharmacy 17\n",
"Plaza 16\n",
"Grocery Store 15\n",
"Cosmetics Shop 15\n",
"Sandwich Place 15\n",
"Farmers Market 13\n",
"Department Store 13\n",
"Electronics Store 13\n",
"Bar 13\n",
"Fast Food Restaurant 13\n",
"Chinese Restaurant 13\n",
"Middle Eastern Restaurant 12\n",
"Salon / Barbershop 12\n",
"Cupcake Shop 11\n",
"Doner Restaurant 11\n",
"Furniture / Home Store 11\n",
"Lebanese Restaurant 11\n",
"Bookstore 10\n",
"Steakhouse 10\n",
"Sushi Restaurant 10\n",
"Ice Cream Shop 10\n",
"Pool 9\n",
"Turkish Restaurant 9\n",
"Nightclub 9\n",
"Mediterranean Restaurant 9\n",
"Spa 8\n",
"Beer Garden 8\n",
"Hostel 7\n",
"Tea Room 7\n",
"Wine Bar 7\n",
"Mobile Phone Shop 7\n",
"Soccer Field 7\n",
"Shopping Mall 7\n",
"Theater 7\n",
"Seafood Restaurant 7\n",
"Greek Restaurant 6\n",
"Casino 6\n",
"Health & Beauty Service 6\n",
"Light Rail Station 6\n",
"Cocktail Bar 6\n",
"Sporting Goods Shop 6\n",
"Snack Place 5\n",
"Roof Deck 5\n",
"Bagel Shop 5\n",
"Gastropub 5\n",
"Food & Drink Shop 5\n",
"Salad Place 5\n",
"Multiplex 5\n",
"Garden 5\n",
"French Restaurant 4\n",
"American Restaurant 4\n",
"Diner 4\n",
"Asian Restaurant 4\n",
"Vietnamese Restaurant 4\n",
"Tram Station 4\n",
"Metro Station 4\n",
"History Museum 4\n",
"Modern European Restaurant 3\n",
"German Restaurant 3\n",
"Market 3\n",
"Accessories Store 3\n",
"Hardware Store 3\n",
"Historic Site 3\n",
"Women's Store 3\n",
"Shoe Store 3\n",
"Chocolate Shop 3\n",
"Art Gallery 3\n",
"Art Museum 3\n",
"Arts & Crafts Store 3\n",
"Wine Shop 3\n",
"Vegetarian / Vegan Restaurant 3\n",
"Toy / Game Store 3\n",
"Tennis Court 3\n",
"Beer Bar 3\n",
"Spanish Restaurant 3\n",
"Palace 3\n",
"Dance Studio 3\n",
"Concert Hall 3\n",
"Convenience Store 3"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print('Top 100 distinct venue counts are as below')\n",
"neighborhood_venues[['VenueId','VenueCategory']].drop_duplicates().groupby('VenueCategory').count()[['VenueId']].rename(columns={\"VenueId\": \"Count\"}).sort_values(by=['Count'], ascending=False)[:100]"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total number of youth enjoyment places: 179\n",
"Total number of alcoholic places : 36\n",
"Percentage of alcoholic places: 20.11%\n"
]
}
],
"source": [
"restaurant_list =['Convenience Store', 'Dance Studio','Bar',\n",
" 'Casino','Theater','Gym / Fitness Center','Gym','Beer Bar','Wine Shop','Chocolate Shop','Garden','Multiplex',\n",
" 'Food & Drink Shop', 'Cocktail Bar']\n",
"turkish_restaurant_list = ['Bar','Beer Bar','Wine Shop','Food & Drink Shop', 'Cocktail Bar', 'Casino']\n",
"\n",
"# Filter restaurants \n",
" \n",
"neighborhood_venues['RestFlag']=False\n",
"for restCat in restaurant_list:\n",
" neighborhood_venues['RestFlag'] = neighborhood_venues['RestFlag'] | neighborhood_venues['VenueCategory'].str.contains(restCat)\n",
" \n",
"neighborhood_restaurants = neighborhood_venues[neighborhood_venues['RestFlag'] == True].iloc[:,:-1]\n",
"turkish_restaurants = neighborhood_restaurants[ neighborhood_restaurants['VenueCategory'].isin(turkish_restaurant_list) ]\n",
"other_restaurants = neighborhood_restaurants[ ~neighborhood_restaurants['VenueCategory'].isin(turkish_restaurant_list) ]\n",
"\n",
"print('Total number of youth enjoyment places:', len(neighborhood_restaurants['VenueId'].unique()))\n",
"print('Total number of alcoholic places :', len(turkish_restaurants['VenueId'].unique()))\n",
"print('Percentage of alcoholic places: {:.2f}%'.format(len(turkish_restaurants['VenueId'].unique()) / len(neighborhood_restaurants['VenueId'].unique()) * 100))"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11 neighborhoods do not have any alcoholic places\n"
]
},
{
"data": {
"image/png": "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NYqDDjqIBQsWALDmmmvWHbMvRWa2JnDERsBGmTkzItYCZgAfBY4E5mXm5LKge2tmfrnTvoOB/wPeD8wB7gYOzcwHujvmhAkT0gu4S5IkST178MEHede73rXk/ohJ05oaf/bkfXvcZs011+TVV19t6nFbpTLXww47jG222YYTTjihXx9D59cQICJmZOaEztu2rMUvM5/JzJnl7fnAg8AmwEeA88rNzqMoBjvbDngkMx/LzL8DF5f7SZIkSWpzI0aM4KSTTmL8+PGMHj2ahx56CIBzzz2X448/HoDHH3+cPfbYgzFjxrDHHnvwxBNPMH/+fEaOHMkbb7wBwCuvvMKIESN44403OPLII7n88su7jf/CCy/w/ve/n/Hjx3PMMcew2Wab8eKLLy6T384778wjjzyy1LJXX32VPfbYY0nMq666asm6888/nzFjxjB27FgOP/zwJcc64IAD2Hbbbdl222357W9/C8Ctt966pAV06623Zv78+U15TvtkjF9EjAC2Bu4CNszMZ6AoDoENquyyCfBkxf055TJJkiRJbeJvf/vbUl09L7nkkiXrhg4dysyZM/nMZz7Daaedtsy+xx9/PBMnTuS+++7jsMMO43Of+xxrrbUWu+22G9OmFa2XF198MQcccEDVSx5Ui3/KKaew++67M3PmTPbbbz+eeOKJZfZbuHAh1157LaNHj15q+ZAhQ5g6dSozZ87klltu4Ytf/CKZyf3338/XvvY1br75Zu69916+973vAfD5z3+ef/mXf+Huu+/m5z//OZ/61KcAOO200/jBD37ArFmz+M1vfsNqq61W57O7tJZfziEi1gR+DnwhM1+pcRBitY2q9kmNiKOBowGGDx++zPpqTda1NDtLkiRJaq3VVluNWbNmVV23//77A7DNNttwxRVXLLP+zjvvXLL88MMP50tf+hIAn/rUp/jWt77FRz/6Uc455xzOOuusmuPffvvtTJ06FYC9996bt771zelIOopUKFr8PvnJTy4VLzP5yle+wm233cagQYN46qmneO6557j55ps58MADGTp0KADrrrsuADfeeCMPPPDmSLZXXnmF+fPns+OOO3LCCSdw2GGHsf/++zNs2LAun7/eaGnhFxErUxR9F2Zmx6v1XERslJnPlOMAn6+y6xxg04r7w4Cnqx0jM88EzoRijF/TkpckSZLUb1ZddVWgmFRl4cKFPW7f0cC04447Mnv2bG699VYWLVrEqFGjao7f3fwn3RWpABdeeCEvvPACM2bMYOWVV2bEiBG89tprZGbVGTgXL17MnXfeuUyL3qRJk9h333255ppr2H777bnxxhvZcsstu3/wNWjlrJ4BnA08mJn/U7HqauCI8vYRwFWd96WYzGXziBgZEasAh5T7SZIkSRI77LADF198MVAUXTvttNOSdRMnTuTQQw/lqKOO6lXMnXbaiUsvvRSA66+/nr/85S817/vyyy+zwQYbsPLKK3PLLbfw+OOPA7DHHntw6aWXMnfuXADmzZsHwF577cUZZ5yxZP+OovLRRx9l9OjRfPnLX2bChAlLxh82qpVj/HYEDgd2j4hZ5c8HgMnA+yPiTxSzdk4GiIiNI+IagMxcCBwPXEcxKcylmXl/C3OVJEmS1Mc6j/GbNKnnq7h1tJ59//vf55xzzmHMmDFccMEFS8bOQTHr5l/+8hcOPfTQXuVz0kkncf311zN+/HiuvfZaNtpoI9Zaa62a9j3ssMOYPn06EyZM4MILL1zSSvfud7+br371q+y6666MHTuWE044YUn+06dPZ8yYMWy11VZMmTIFgO9+97uMGjWKsWPHstpqq7HPPvv06jF0pWWXc+gP1S7n4Bg/SZIkaVnVLgWwvPv2t7/NK6+8wimnnNLtdpdffjlXXXUVF1xwQa/iv/766wwePJiVVlqJO++8k8985jPddu/sb725nEPLJ3eRJEmSpEZNmTKFc889t+pEL5U++9nPcu2113LNNdf0+hhPPPEEBx98MIsXL2aVVVbpcmKYgcjCT5IkSdJy79hjj+XYY4/tcbvTTz+97mNsvvnm3HPPPXXvvzzrk+v4SZIkSZL6j4WfJEmSJLU5Cz9JkiRJanMWfpIkSZLU5iz8JEmSJPWbqVOnEhFLLlQ+e/ZsRo0aVVesESNG8OKLL9a8/bnnnsvxxx8PFLOGnn/++V1uO3v2bFZbbTXGjRvHVlttxbHHHsvixYsbyrcvOaunJEmSJDh5nSbHe7mmzS666CJ22mknLr74Yk4++eTm5tALtcwY+o53vINZs2axcOFCdt99d6688krGjx/fB9k1zhY/SZIkSf3i1Vdf5be//S1nn302F1988TLrFy1axL/+678yevRoxowZs+RSDTfddBNbb701o0eP5hOf+ASvv/76kn1OP/10xo8fz+jRo5e0Is6bN4+PfvSjjBkzhu2335777rtvmWOdfPLJnHbaaQA88sgj7LnnnowdO5bx48fz6KOPLrXtSiutxA477MAjjzyy1PLZs2ez8847M378eMaPH88dd9yxZN23vvUtRo8ezdixY5k0aRIAjz76KHvvvTfbbLMNO++885J8L7vsMkaNGsXYsWPZZZddev28VmOLnyRJkqR+ceWVV7L33nuzxRZbsO666zJz5kzWXXfdJevPPPNM/vznP3PPPfew0korMW/ePF577TWOPPJIbrrpJrbYYgsmTpzIj370I77whS8AMHToUGbOnMkPf/hDTjvtNH7yk59w0kknsfXWW3PllVdy8803M3HiRGbNmtVlXocddhiTJk1iv/3247XXXmPx4sU8//zzS9YvWLCAm266iVNPPXWp/TbYYANuuOEGhgwZwp/+9CcOPfRQpk+fzrXXXsuVV17JXXfdxeqrr868efMAOProo5kyZQqbb745d911F8cddxw333wzp556Ktdddx2bbLIJL730UlOea1v8JEmSJPWLiy66iEMOOQSAQw45hIsuumip9TfeeCPHHnssK61UtFetu+66PPzww4wcOZItttgCgCOOOILbbrttyT77778/ANtssw2zZ88G4Pbbb+fwww8HYPfdd2fu3Lm8/HL1rqjz58/nqaeeYr/99gNgyJAhrL766kDRQjdu3Dh23HFH9t13X/bZZ5+l9n3jjTf49Kc/zejRoznooIN44IEHljyOo446akmcddddl1dffZU77riDgw46iHHjxnHMMcfwzDPPALDjjjty5JFHctZZZ7Fo0aLePq1V2eInSZIkqc/NnTuXm2++mT/+8Y9EBIsWLSIiOO6445Zsk5lExFL7ZWa3cVdddVUABg8ezMKFC7vcp3PcWuJ3jPHryne+8x023HBD7r33XhYvXsyQIUO6fByLFy/mLW95S9V4U6ZM4a677mLatGmMGzeOWbNmsd5663V53FrY4idJkiSpz11++eVMnDiRxx9/nNmzZ/Pkk08ycuRI5syZs2SbvfbaiylTpiwp4ObNm8eWW27J7Nmzl4yvu+CCC9h11127PdYuu+zChRdeCMCvf/1rhg4dytprr11127XXXpthw4Zx5ZVXAvD666+zYMGCmh7Tyy+/zEYbbcSgQYO44IILlrTW7bXXXvz0pz9dEmfe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\n",
"text/plain": [
"<Figure size 1080x360 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# get counts of restaurants in each Neighborhood\n",
"df_rest_counts = neighborhood_restaurants.groupby(['Neighborhood']).count().rename(columns={\"VenueCategory\": \"EnjoyingPlaces\"})[['EnjoyingPlaces']]\n",
"\n",
"#find neighborhoods that does not have any restaurant \n",
"noRestList = list(set(neighborhood_venues['Neighborhood']) - set(neighborhood_restaurants['Neighborhood']))\n",
"\n",
"#if exists , append neighborhoods without any restaurant to df_rest_counts\n",
"if noRestList != []:\n",
" df_rest_counts = df_rest_counts.append (pd.DataFrame( {'Neighborhood' : noRestList , 'EnjoyingPlaces': [0] * len(noRestList) } ).set_index('Neighborhood'))\n",
"\n",
"df_rest_counts.reset_index(inplace=True)\n",
"\n",
"#####\n",
"# get counts of Turkish restaurants in each Neighborhood\n",
"df_turk_rest_counts = turkish_restaurants.groupby(['Neighborhood']).count().rename(columns={\"VenueCategory\": \"AlcoholicPlaces\"})[['AlcoholicPlaces']]\n",
"\n",
"#find neighborhoods that does not have any restaurant \n",
"noRestList = list(set(neighborhood_venues['Neighborhood']) - set(turkish_restaurants['Neighborhood']))\n",
"\n",
"#if exists , append neighborhoods without any restaurant to df_rest_counts\n",
"if noRestList != []:\n",
" df_turk_rest_counts = df_turk_rest_counts.append (pd.DataFrame( {'Neighborhood' : noRestList , 'AlcoholicPlaces': [0] * len(noRestList) } ).set_index('Neighborhood'))\n",
"\n",
"df_turk_rest_counts.reset_index(inplace=True)\n",
"df_rest_counts= df_rest_counts.merge(df_turk_rest_counts).set_index('Neighborhood')\n",
"df_rest_counts= df_rest_counts.sort_values(by=['EnjoyingPlaces'],ascending =False)\n",
"\n",
"print('{} neighborhoods do not have any alcoholic places'.format(len(noRestList)))\n",
"######\n",
"#Draw graph\n",
"df_rest_counts[['EnjoyingPlaces','AlcoholicPlaces']].plot(kind='bar',figsize=(15,5))\n",
"plt.title('Alcoholic Counts of Neighborhoods')\n",
"plt.xlabel('Neighborhood')\n",
"plt.ylabel('Alcoholic Counts')\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>VenueId</th>\n",
" <th>VenueRating</th>\n",
" <th>VenueLikes</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>4d7731aebc888cfac2f5e573</td>\n",
" <td>7.6</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>5abf8bf49fca567ea381ee43</td>\n",
" <td>7.5</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>5dde6a94af03f30008bfeb22</td>\n",
" <td>7.5</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>529e0ff211d2ee9c61e157e7</td>\n",
" <td>7.7</td>\n",
" <td>55.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>525d091a498edd52e72a51e4</td>\n",
" <td>6.6</td>\n",
" <td>8.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" VenueId VenueRating VenueLikes\n",
"0 4d7731aebc888cfac2f5e573 7.6 4.0\n",
"1 5abf8bf49fca567ea381ee43 7.5 23.0\n",
"2 5dde6a94af03f30008bfeb22 7.5 0.0\n",
"3 529e0ff211d2ee9c61e157e7 7.7 55.0\n",
"4 525d091a498edd52e72a51e4 6.6 8.0"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def getVenueRaitings(venues):\n",
" \n",
" raitings = []\n",
" likes =[]\n",
" for venueId in venues:\n",
"\n",
" # create the API request URL\n",
" url = 'https://api.foursquare.com/v2/venues/{}?client_id={}&client_secret={}&v={}'.format(venueId, CLIENT_ID, CLIENT_SECRET, VERSION)\n",
" result = requests.get(url).json()\n",
" try:\n",
" rating = result['response']['venue']['rating']\n",
" likes = result['response']['venue']['likes']['count']\n",
" except:\n",
" rating = None\n",
" likes = None\n",
" \n",
" raitings.append((venueId, rating,likes))\n",
" \n",
" # convert the venues list into a DataFrame\n",
" rating = pd.DataFrame(raitings)\n",
" # define the column names\n",
" rating.columns = ['VenueId', 'VenueRating','VenueLikes']\n",
"\n",
" return rating \n",
"\n",
"restaurants_raitings = getVenueRaitings(neighborhood_restaurants['VenueId'].drop_duplicates())\n",
"restaurants_raitings.head()"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>VenueName</th>\n",
" <th>VenueId</th>\n",
" <th>VenueLatitude</th>\n",
" <th>VenueLongitude</th>\n",
" <th>VenueDistance</th>\n",
" <th>VenueCategory</th>\n",
" <th>VenueRating</th>\n",
" <th>VenueLikes</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>Toni&amp;Guy</td>\n",
" <td>4d7731aebc888cfac2f5e573</td>\n",
" <td>44.484375</td>\n",
" <td>26.092021</td>\n",
" <td>747</td>\n",
" <td>Salon / Barbershop</td>\n",
" <td>7.6</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>Hangar Gastrobar</td>\n",
" <td>5abf8bf49fca567ea381ee43</td>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" <td>701</td>\n",
" <td>Beer Garden</td>\n",
" <td>7.5</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Floreasca</td>\n",
" <td>44.476308</td>\n",
" <td>26.103289</td>\n",
" <td>Hangar Gastrobar</td>\n",
" <td>5abf8bf49fca567ea381ee43</td>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" <td>494</td>\n",
" <td>Beer Garden</td>\n",
" <td>7.5</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>World Class Romania</td>\n",
" <td>5dde6a94af03f30008bfeb22</td>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" <td>739</td>\n",
" <td>Gym / Fitness Center</td>\n",
" <td>7.5</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Floreasca</td>\n",
" <td>44.476308</td>\n",
" <td>26.103289</td>\n",
" <td>World Class Romania</td>\n",
" <td>5dde6a94af03f30008bfeb22</td>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" <td>542</td>\n",
" <td>Gym / Fitness Center</td>\n",
" <td>7.5</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Latitude Longitude VenueName \\\n",
"0 Aviației 44.485790 26.101219 Toni&Guy \n",
"1 Aviației 44.485790 26.101219 Hangar Gastrobar \n",
"2 Floreasca 44.476308 26.103289 Hangar Gastrobar \n",
"3 Aviației 44.485790 26.101219 World Class Romania \n",
"4 Floreasca 44.476308 26.103289 World Class Romania \n",
"\n",
" VenueId VenueLatitude VenueLongitude VenueDistance \\\n",
"0 4d7731aebc888cfac2f5e573 44.484375 26.092021 747 \n",
"1 5abf8bf49fca567ea381ee43 44.480385 26.105761 701 \n",
"2 5abf8bf49fca567ea381ee43 44.480385 26.105761 494 \n",
"3 5dde6a94af03f30008bfeb22 44.480482 26.106822 739 \n",
"4 5dde6a94af03f30008bfeb22 44.480482 26.106822 542 \n",
"\n",
" VenueCategory VenueRating VenueLikes \n",
"0 Salon / Barbershop 7.6 4.0 \n",
"1 Beer Garden 7.5 23.0 \n",
"2 Beer Garden 7.5 23.0 \n",
"3 Gym / Fitness Center 7.5 0.0 \n",
"4 Gym / Fitness Center 7.5 0.0 "
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#merge raitings to restaurants \n",
"neighborhood_restaurants = neighborhood_restaurants.merge(restaurants_raitings)\n",
"neighborhood_restaurants.head()"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>VenueName</th>\n",
" <th>VenueId</th>\n",
" <th>VenueLatitude</th>\n",
" <th>VenueLongitude</th>\n",
" <th>VenueDistance</th>\n",
" <th>VenueCategory</th>\n",
" <th>VenueRating</th>\n",
" <th>VenueLikes</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>Toni&amp;Guy</td>\n",
" <td>4d7731aebc888cfac2f5e573</td>\n",
" <td>44.484375</td>\n",
" <td>26.092021</td>\n",
" <td>747</td>\n",
" <td>Salon / Barbershop</td>\n",
" <td>7.6</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>Hangar Gastrobar</td>\n",
" <td>5abf8bf49fca567ea381ee43</td>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" <td>701</td>\n",
" <td>Beer Garden</td>\n",
" <td>7.5</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Floreasca</td>\n",
" <td>44.476308</td>\n",
" <td>26.103289</td>\n",
" <td>Hangar Gastrobar</td>\n",
" <td>5abf8bf49fca567ea381ee43</td>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" <td>494</td>\n",
" <td>Beer Garden</td>\n",
" <td>7.5</td>\n",
" <td>23.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Aviației</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>World Class Romania</td>\n",
" <td>5dde6a94af03f30008bfeb22</td>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" <td>739</td>\n",
" <td>Gym / Fitness Center</td>\n",
" <td>7.5</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Floreasca</td>\n",
" <td>44.476308</td>\n",
" <td>26.103289</td>\n",
" <td>World Class Romania</td>\n",
" <td>5dde6a94af03f30008bfeb22</td>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" <td>542</td>\n",
" <td>Gym / Fitness Center</td>\n",
" <td>7.5</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Latitude Longitude VenueName \\\n",
"0 Aviației 44.485790 26.101219 Toni&Guy \n",
"1 Aviației 44.485790 26.101219 Hangar Gastrobar \n",
"2 Floreasca 44.476308 26.103289 Hangar Gastrobar \n",
"3 Aviației 44.485790 26.101219 World Class Romania \n",
"4 Floreasca 44.476308 26.103289 World Class Romania \n",
"\n",
" VenueId VenueLatitude VenueLongitude VenueDistance \\\n",
"0 4d7731aebc888cfac2f5e573 44.484375 26.092021 747 \n",
"1 5abf8bf49fca567ea381ee43 44.480385 26.105761 701 \n",
"2 5abf8bf49fca567ea381ee43 44.480385 26.105761 494 \n",
"3 5dde6a94af03f30008bfeb22 44.480482 26.106822 739 \n",
"4 5dde6a94af03f30008bfeb22 44.480482 26.106822 542 \n",
"\n",
" VenueCategory VenueRating VenueLikes \n",
"0 Salon / Barbershop 7.6 4.0 \n",
"1 Beer Garden 7.5 23.0 \n",
"2 Beer Garden 7.5 23.0 \n",
"3 Gym / Fitness Center 7.5 0.0 \n",
"4 Gym / Fitness Center 7.5 0.0 "
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#merge raitings to restaurants \n",
"neighborhood_restaurants = neighborhood_restaurants.merge(restaurants_raitings)\n",
"neighborhood_restaurants.head()"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>VenueLatitude</th>\n",
" <th>VenueLongitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>44.484375</td>\n",
" <td>26.092021</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>44.480385</td>\n",
" <td>26.105761</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>44.480482</td>\n",
" <td>26.106822</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" VenueLatitude VenueLongitude\n",
"0 44.484375 26.092021\n",
"1 44.480385 26.105761\n",
"2 44.480385 26.105761\n",
"3 44.480482 26.106822\n",
"4 44.480482 26.106822"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data=neighborhood_restaurants[['VenueLatitude','VenueLongitude']]\n",
"data.head()\n",
"#data.dtypes"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "must be real number, not str",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-65-bd4704df7651>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTileLayer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'cartodbpositron'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_bucharest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mHeatMap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_restaurant\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMarker\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbucharest_center\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_bucharest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCircle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbucharest_center\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mradius\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2000\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfill\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'white'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_restaurant\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/plugins/heat_map.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, name, min_opacity, max_zoom, max_val, radius, blur, gradient, overlay)\u001b[0m\n\u001b[1;32m 43\u001b[0m max_val=1.0, radius=25, blur=15, gradient=None, overlay=True):\n\u001b[1;32m 44\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mTileLayer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 45\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\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[0m\u001b[1;32m 46\u001b[0m raise ValueError('data cannot contain NaNs, '\n\u001b[1;32m 47\u001b[0m 'got:\\n{!r}'.format(data))\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/utilities.py\u001b[0m in \u001b[0;36m_isnan\u001b[0;34m(values)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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 71\u001b[0m \u001b[0;34m\"\"\"Check if there are NaNs values in the iterable.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 72\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0m_flatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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[0m\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/utilities.py\u001b[0m in \u001b[0;36m<genexpr>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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 71\u001b[0m \u001b[0;34m\"\"\"Check if there are NaNs values in the iterable.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 72\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0m_flatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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[0m\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mTypeError\u001b[0m: must be real number, not str"
]
}
],
"source": [
"bucharest_center = [latitude, longitude]\n",
"map_restaurant= folium.Map(location=bucharest_center, zoom_start=12)\n",
"df_neighborhood_noturkrest = df_neighborhood[df_neighborhood['Neighborhood'].isin(noRestList)]\n",
"\n",
"folium.TileLayer('cartodbpositron').add_to(map_bucharest) \n",
"HeatMap(data).add_to(map_restaurant)\n",
"folium.Marker(bucharest_center).add_to(map_bucharest)\n",
"folium.Circle(bucharest_center, radius=2000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=4000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=6000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=10000, fill=False, color='black').add_to(map_restaurant)\n",
"for lat, lon, neig, name in zip(turkish_restaurants['VenueLatitude'], turkish_restaurants['VenueLongitude'], turkish_restaurants['Neighborhood'], turkish_restaurants['VenueName']):\n",
" label = folium.Popup(str(name) + ' - ' + str(neig), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color='red',\n",
" fill=True,\n",
" fill_color='#3186cc',\n",
" fill_opacity=0.7).add_to(map_restaurant)\n",
" \n",
"raiting_lt_7 = turkish_restaurants[turkish_restaurants['VenueRating'] <7]\n",
"for lat, lon, neig, name in zip(raiting_lt_7['VenueLatitude'], raiting_lt_7['VenueLongitude'], raiting_lt_7['Neighborhood'], raiting_lt_7['VenueName']):\n",
" label = folium.Popup(str(name) + ' - ' + str(neig), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color='blue',\n",
" fill=True,\n",
" fill_color='#3186cc',\n",
" fill_opacity=0.7).add_to(map_restaurant) \n",
"map_restaurant"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "must be real number, not str",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-66-c0a05efaf496>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTileLayer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'cartodbpositron'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_bucharest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mHeatMap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mneighborhood_restaurants\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'VenueLatitude'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'VenueLongitude'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_restaurant\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMarker\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbucharest_center\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_bucharest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mfolium\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mCircle\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbucharest_center\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mradius\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m2000\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfill\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolor\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'white'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmap_restaurant\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/plugins/heat_map.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, name, min_opacity, max_zoom, max_val, radius, blur, gradient, overlay)\u001b[0m\n\u001b[1;32m 43\u001b[0m max_val=1.0, radius=25, blur=15, gradient=None, overlay=True):\n\u001b[1;32m 44\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mTileLayer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 45\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\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[0m\u001b[1;32m 46\u001b[0m raise ValueError('data cannot contain NaNs, '\n\u001b[1;32m 47\u001b[0m 'got:\\n{!r}'.format(data))\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/utilities.py\u001b[0m in \u001b[0;36m_isnan\u001b[0;34m(values)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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 71\u001b[0m \u001b[0;34m\"\"\"Check if there are NaNs values in the iterable.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 72\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0m_flatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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[0m\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/conda/envs/python/lib/python3.6/site-packages/folium/utilities.py\u001b[0m in \u001b[0;36m<genexpr>\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 70\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_isnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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 71\u001b[0m \u001b[0;34m\"\"\"Check if there are NaNs values in the iterable.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 72\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misnan\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;32min\u001b[0m \u001b[0m_flatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\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[0m\u001b[1;32m 73\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 74\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mTypeError\u001b[0m: must be real number, not str"
]
}
],
"source": [
"bucharest_center = [latitude, longitude]\n",
"map_restaurant= folium.Map(location=bucharest_center, zoom_start=12)\n",
"\n",
"df_neighborhood_noturkrest = df_neighborhood[df_neighborhood['Neighborhood'].isin(noRestList)]\n",
"\n",
"folium.TileLayer('cartodbpositron').add_to(map_bucharest) \n",
"HeatMap(neighborhood_restaurants[['VenueLatitude','VenueLongitude']]).add_to(map_restaurant)\n",
"folium.Marker(bucharest_center).add_to(map_bucharest)\n",
"folium.Circle(bucharest_center, radius=2000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=4000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=6000, fill=False, color='white').add_to(map_restaurant)\n",
"folium.Circle(bucharest_center, radius=10000, fill=False, color='black').add_to(map_restaurant)\n",
"for lat, lon, neig in zip(df_neighborhood_noturkrest['Latitude'], df_neighborhood_noturkrest['Longitude'], df_neighborhood_noturkrest['Neighborhood']):\n",
" label = folium.Popup(str(neig), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color='cyan',\n",
" fill=True,\n",
" fill_color='cyan',\n",
" fill_opacity=0.7).add_to(map_restaurant)\n",
"map_restaurant"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"40 neighborhoods' venue category are shown in 224 columns as below\n"
]
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Hotel</th>\n",
" <th>Supermarket</th>\n",
" <th>Coffee Shop</th>\n",
" <th>Burger Joint</th>\n",
" <th>Dessert Shop</th>\n",
" <th>Roof Deck</th>\n",
" <th>Grocery Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Salad Place</th>\n",
" <th>Salon / Barbershop</th>\n",
" <th>Bookstore</th>\n",
" <th>Beer Garden</th>\n",
" <th>Gym / Fitness Center</th>\n",
" <th>Restaurant</th>\n",
" <th>Steakhouse</th>\n",
" <th>Café</th>\n",
" <th>Pie Shop</th>\n",
" <th>Bakery</th>\n",
" <th>Shopping Mall</th>\n",
" <th>Italian Restaurant</th>\n",
" <th>Clothing Store</th>\n",
" <th>Sushi Restaurant</th>\n",
" <th>Turkish Restaurant</th>\n",
" <th>Toy / Game Store</th>\n",
" <th>Lebanese Restaurant</th>\n",
" <th>Sandwich Place</th>\n",
" <th>Spanish Restaurant</th>\n",
" <th>Casino</th>\n",
" <th>Pizza Place</th>\n",
" <th>Middle Eastern Restaurant</th>\n",
" <th>Event Space</th>\n",
" <th>Indoor Play Area</th>\n",
" <th>Lounge</th>\n",
" <th>Eastern European Restaurant</th>\n",
" <th>Fried Chicken Joint</th>\n",
" <th>Farmers Market</th>\n",
" <th>Stadium</th>\n",
" <th>Gym</th>\n",
" <th>Romanian Restaurant</th>\n",
" <th>Lighting Store</th>\n",
" <th>Mongolian Restaurant</th>\n",
" <th>Tennis Stadium</th>\n",
" <th>Chinese Restaurant</th>\n",
" <th>Ice Cream Shop</th>\n",
" <th>Sporting Goods Shop</th>\n",
" <th>Cocktail Bar</th>\n",
" <th>Cupcake Shop</th>\n",
" <th>Food &amp; Drink Shop</th>\n",
" <th>Doner Restaurant</th>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <th>Lake</th>\n",
" <th>Nightclub</th>\n",
" <th>Park</th>\n",
" <th>Theme Restaurant</th>\n",
" <th>Tunnel</th>\n",
" <th>Bed &amp; Breakfast</th>\n",
" <th>Soccer Field</th>\n",
" <th>Electronics Store</th>\n",
" <th>Nature Preserve</th>\n",
" <th>Fast Food Restaurant</th>\n",
" <th>Pharmacy</th>\n",
" <th>Fountain</th>\n",
" <th>Metro Station</th>\n",
" <th>Gas Station</th>\n",
" <th>Mobile Phone Shop</th>\n",
" <th>Spa</th>\n",
" <th>Korean Restaurant</th>\n",
" <th>Shop &amp; Service</th>\n",
" <th>Bistro</th>\n",
" <th>Outdoor Sculpture</th>\n",
" <th>Gastropub</th>\n",
" <th>Theater</th>\n",
" <th>Monastery</th>\n",
" <th>Indie Theater</th>\n",
" <th>Skating Rink</th>\n",
" <th>Beer Bar</th>\n",
" <th>Used Bookstore</th>\n",
" <th>Chocolate Shop</th>\n",
" <th>Tea Room</th>\n",
" <th>Art Museum</th>\n",
" <th>Bar</th>\n",
" <th>Wine Bar</th>\n",
" <th>Concert Hall</th>\n",
" <th>Plaza</th>\n",
" <th>Cosmetics Shop</th>\n",
" <th>Rock Club</th>\n",
" <th>Swiss Restaurant</th>\n",
" <th>Hostel</th>\n",
" <th>Historic Site</th>\n",
" <th>Art Gallery</th>\n",
" <th>Tattoo Parlor</th>\n",
" <th>Mediterranean Restaurant</th>\n",
" <th>Church</th>\n",
" <th>History Museum</th>\n",
" <th>Gourmet Shop</th>\n",
" <th>Boutique</th>\n",
" <th>French Restaurant</th>\n",
" <th>Garden</th>\n",
" <th>Hardware Store</th>\n",
" <th>Discount Store</th>\n",
" <th>Arts &amp; Crafts Store</th>\n",
" <th>Bus Station</th>\n",
" <th>Furniture / Home Store</th>\n",
" <th>Gift Shop</th>\n",
" <th>Tennis Court</th>\n",
" <th>Accessories Store</th>\n",
" <th>Jazz Club</th>\n",
" <th>Market</th>\n",
" <th>Opera House</th>\n",
" <th>Hotel Bar</th>\n",
" <th>Pub</th>\n",
" <th>Indian Restaurant</th>\n",
" <th>Music Store</th>\n",
" <th>Pool</th>\n",
" <th>Pedestrian Plaza</th>\n",
" <th>Indie Movie Theater</th>\n",
" <th>Australian Restaurant</th>\n",
" <th>Martial Arts Dojo</th>\n",
" <th>Light Rail Station</th>\n",
" <th>Department Store</th>\n",
" <th>Climbing Gym</th>\n",
" <th>Soccer Stadium</th>\n",
" <th>Miscellaneous Shop</th>\n",
" <th>Sake Bar</th>\n",
" <th>Convenience Store</th>\n",
" <th>Outlet Mall</th>\n",
" <th>Veterinarian</th>\n",
" <th>Mexican Restaurant</th>\n",
" <th>Flower Shop</th>\n",
" <th>Fish Market</th>\n",
" <th>Japanese Restaurant</th>\n",
" <th>Juice Bar</th>\n",
" <th>Scandinavian Restaurant</th>\n",
" <th>Cheese Shop</th>\n",
" <th>Asian Restaurant</th>\n",
" <th>Modern European Restaurant</th>\n",
" <th>Seafood Restaurant</th>\n",
" <th>Creperie</th>\n",
" <th>Wine Shop</th>\n",
" <th>German Restaurant</th>\n",
" <th>Molecular Gastronomy Restaurant</th>\n",
" <th>Hookah Bar</th>\n",
" <th>American Restaurant</th>\n",
" <th>Drugstore</th>\n",
" <th>Auto Workshop</th>\n",
" <th>Pet Store</th>\n",
" <th>Multiplex</th>\n",
" <th>Eye Doctor</th>\n",
" <th>Skate Park</th>\n",
" <th>Greek Restaurant</th>\n",
" <th>Water Park</th>\n",
" <th>Brewery</th>\n",
" <th>Playground</th>\n",
" <th>Ballroom</th>\n",
" <th>Tourist Information Center</th>\n",
" <th>Bus Line</th>\n",
" <th>Butcher</th>\n",
" <th>Health &amp; Beauty Service</th>\n",
" <th>Health Food Store</th>\n",
" <th>Camera Store</th>\n",
" <th>Bagel Shop</th>\n",
" <th>Falafel Restaurant</th>\n",
" <th>Diner</th>\n",
" <th>Auto Dealership</th>\n",
" <th>Portuguese Restaurant</th>\n",
" <th>Science Museum</th>\n",
" <th>Perfume Shop</th>\n",
" <th>Snack Place</th>\n",
" <th>Lingerie Store</th>\n",
" <th>Ramen Restaurant</th>\n",
" <th>Cafeteria</th>\n",
" <th>Tram Station</th>\n",
" <th>Boxing Gym</th>\n",
" <th>Museum</th>\n",
" <th>Food Truck</th>\n",
" <th>Buffet</th>\n",
" <th>Movie Theater</th>\n",
" <th>Kebab Restaurant</th>\n",
" <th>Exhibit</th>\n",
" <th>Public Art</th>\n",
" <th>Pool Hall</th>\n",
" <th>RV Park</th>\n",
" <th>Women's Store</th>\n",
" <th>Palace</th>\n",
" <th>Cultural Center</th>\n",
" <th>Football Stadium</th>\n",
" <th>Shoe Store</th>\n",
" <th>BBQ Joint</th>\n",
" <th>Hungarian Restaurant</th>\n",
" <th>Karaoke Bar</th>\n",
" <th>Donut Shop</th>\n",
" <th>Beach</th>\n",
" <th>Auto Garage</th>\n",
" <th>Currency Exchange</th>\n",
" <th>Athletics &amp; Sports</th>\n",
" <th>Sports Club</th>\n",
" <th>Food</th>\n",
" <th>Go Kart Track</th>\n",
" <th>IT Services</th>\n",
" <th>Souvlaki Shop</th>\n",
" <th>Track</th>\n",
" <th>Gym Pool</th>\n",
" <th>Recreation Center</th>\n",
" <th>Bike Shop</th>\n",
" <th>Basketball Court</th>\n",
" <th>Paper / Office Supplies Store</th>\n",
" <th>Bowling Alley</th>\n",
" <th>Sports Bar</th>\n",
" <th>Laundromat</th>\n",
" <th>Baby Store</th>\n",
" <th>Comfort Food Restaurant</th>\n",
" <th>Taco Place</th>\n",
" <th>Watch Shop</th>\n",
" <th>Smoke Shop</th>\n",
" <th>Fish &amp; Chips Shop</th>\n",
" <th>Betting Shop</th>\n",
" <th>ATM</th>\n",
" <th>Soup Place</th>\n",
" <th>Circus</th>\n",
" <th>Dance Studio</th>\n",
" <th>Pet Café</th>\n",
" <th>Leather Goods Store</th>\n",
" <th>Gaming Cafe</th>\n",
" <th>Recording Studio</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>13 Septembrie</td>\n",
" <td>2</td>\n",
" <td>3</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>5</td>\n",
" <td>1</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>4</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>3</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Aviației</td>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>7</td>\n",
" <td>3</td>\n",
" <td>5</td>\n",
" <td>1</td>\n",
" <td>5</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>4</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>4</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Berceni</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>3</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Bucureștii Noi</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Băneasa</td>\n",
" <td>2</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Hotel Supermarket Coffee Shop Burger Joint \\\n",
"0 13 Septembrie 2 3 1 0 \n",
"1 Aviației 4 4 3 3 \n",
"2 Berceni 1 0 2 0 \n",
"3 Bucureștii Noi 0 1 0 0 \n",
"4 Băneasa 2 1 0 0 \n",
"\n",
" Dessert Shop Roof Deck Grocery Store Vietnamese Restaurant Salad Place \\\n",
"0 0 0 0 0 0 \n",
"1 2 1 1 1 1 \n",
"2 0 0 2 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Salon / Barbershop Bookstore Beer Garden Gym / Fitness Center \\\n",
"0 0 0 0 2 \n",
"1 1 1 1 2 \n",
"2 0 0 1 2 \n",
"3 0 0 0 0 \n",
"4 0 0 0 1 \n",
"\n",
" Restaurant Steakhouse Café Pie Shop Bakery Shopping Mall \\\n",
"0 5 1 4 0 0 0 \n",
"1 7 3 5 1 5 1 \n",
"2 0 0 0 0 0 0 \n",
"3 1 0 0 0 0 0 \n",
"4 2 0 2 0 0 0 \n",
"\n",
" Italian Restaurant Clothing Store Sushi Restaurant Turkish Restaurant \\\n",
"0 1 2 0 0 \n",
"1 1 4 2 1 \n",
"2 1 0 0 0 \n",
"3 0 0 0 0 \n",
"4 2 0 0 0 \n",
"\n",
" Toy / Game Store Lebanese Restaurant Sandwich Place Spanish Restaurant \\\n",
"0 0 0 0 0 \n",
"1 1 2 1 1 \n",
"2 0 1 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 1 0 \n",
"\n",
" Casino Pizza Place Middle Eastern Restaurant Event Space \\\n",
"0 1 0 0 0 \n",
"1 1 4 1 1 \n",
"2 0 3 0 0 \n",
"3 0 0 0 0 \n",
"4 0 1 1 0 \n",
"\n",
" Indoor Play Area Lounge Eastern European Restaurant Fried Chicken Joint \\\n",
"0 0 2 0 1 \n",
"1 2 1 1 1 \n",
"2 0 0 2 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Farmers Market Stadium Gym Romanian Restaurant Lighting Store \\\n",
"0 1 0 1 2 0 \n",
"1 1 1 2 1 1 \n",
"2 2 0 2 0 0 \n",
"3 1 0 1 0 0 \n",
"4 1 0 0 2 0 \n",
"\n",
" Mongolian Restaurant Tennis Stadium Chinese Restaurant Ice Cream Shop \\\n",
"0 0 0 0 0 \n",
"1 1 1 1 1 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Sporting Goods Shop Cocktail Bar Cupcake Shop Food & Drink Shop \\\n",
"0 0 1 0 0 \n",
"1 1 1 1 1 \n",
"2 0 0 0 1 \n",
"3 0 0 0 0 \n",
"4 0 0 0 1 \n",
"\n",
" Doner Restaurant Vegetarian / Vegan Restaurant Lake Nightclub Park \\\n",
"0 0 0 0 0 1 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 1 \n",
"3 0 0 0 0 1 \n",
"4 1 1 1 1 1 \n",
"\n",
" Theme Restaurant Tunnel Bed & Breakfast Soccer Field Electronics Store \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 1 1 1 1 1 \n",
"\n",
" Nature Preserve Fast Food Restaurant Pharmacy Fountain Metro Station \\\n",
"0 0 1 2 0 0 \n",
"1 0 0 0 0 0 \n",
"2 1 1 2 1 1 \n",
"3 0 0 0 0 1 \n",
"4 0 0 0 0 0 \n",
"\n",
" Gas Station Mobile Phone Shop Spa Korean Restaurant Shop & Service \\\n",
"0 0 0 1 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 1 1 1 1 1 \n",
"4 0 0 0 0 0 \n",
"\n",
" Bistro Outdoor Sculpture Gastropub Theater Monastery Indie Theater \\\n",
"0 1 0 0 1 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Skating Rink Beer Bar Used Bookstore Chocolate Shop Tea Room \\\n",
"0 0 0 0 1 2 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Art Museum Bar Wine Bar Concert Hall Plaza Cosmetics Shop Rock Club \\\n",
"0 1 1 0 0 4 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" Swiss Restaurant Hostel Historic Site Art Gallery Tattoo Parlor \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Mediterranean Restaurant Church History Museum Gourmet Shop Boutique \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" French Restaurant Garden Hardware Store Discount Store \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Arts & Crafts Store Bus Station Furniture / Home Store Gift Shop \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Tennis Court Accessories Store Jazz Club Market Opera House Hotel Bar \\\n",
"0 1 1 1 0 0 1 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Pub Indian Restaurant Music Store Pool Pedestrian Plaza \\\n",
"0 3 1 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Indie Movie Theater Australian Restaurant Martial Arts Dojo \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" Light Rail Station Department Store Climbing Gym Soccer Stadium \\\n",
"0 1 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Miscellaneous Shop Sake Bar Convenience Store Outlet Mall Veterinarian \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Mexican Restaurant Flower Shop Fish Market Japanese Restaurant \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Juice Bar Scandinavian Restaurant Cheese Shop Asian Restaurant \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Modern European Restaurant Seafood Restaurant Creperie Wine Shop \\\n",
"0 0 2 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" German Restaurant Molecular Gastronomy Restaurant Hookah Bar \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" American Restaurant Drugstore Auto Workshop Pet Store Multiplex \\\n",
"0 1 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Eye Doctor Skate Park Greek Restaurant Water Park Brewery Playground \\\n",
"0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Ballroom Tourist Information Center Bus Line Butcher \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Health & Beauty Service Health Food Store Camera Store Bagel Shop \\\n",
"0 0 0 0 1 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Falafel Restaurant Diner Auto Dealership Portuguese Restaurant \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Science Museum Perfume Shop Snack Place Lingerie Store \\\n",
"0 0 0 1 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Ramen Restaurant Cafeteria Tram Station Boxing Gym Museum Food Truck \\\n",
"0 0 0 1 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Buffet Movie Theater Kebab Restaurant Exhibit Public Art Pool Hall \\\n",
"0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" RV Park Women's Store Palace Cultural Center Football Stadium \\\n",
"0 0 0 1 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Shoe Store BBQ Joint Hungarian Restaurant Karaoke Bar Donut Shop \\\n",
"0 0 1 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Beach Auto Garage Currency Exchange Athletics & Sports Sports Club \\\n",
"0 0 0 0 0 0 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Food Go Kart Track IT Services Souvlaki Shop Track Gym Pool \\\n",
"0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Recreation Center Bike Shop Basketball Court \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" Paper / Office Supplies Store Bowling Alley Sports Bar Laundromat \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Baby Store Comfort Food Restaurant Taco Place Watch Shop Smoke Shop \\\n",
"0 0 2 1 1 1 \n",
"1 0 0 0 0 0 \n",
"2 0 0 0 0 0 \n",
"3 0 0 0 0 0 \n",
"4 0 0 0 0 0 \n",
"\n",
" Fish & Chips Shop Betting Shop ATM Soup Place Circus Dance Studio \\\n",
"0 1 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Pet Café Leather Goods Store Gaming Cafe Recording Studio \n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 "
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# one hot encoding\n",
"onehot = pd.get_dummies(neighborhood_venues[['VenueCategory']], prefix=\"\", prefix_sep=\"\")\n",
"# add neighborhood column back to dataframe\n",
"onehot['Neighborhood'] = neighborhood_venues['Neighborhood']\n",
"\n",
"venues_grouped = onehot.groupby([\"Neighborhood\"]).sum().reset_index()\n",
"\n",
"# move neighborhood column to the first column and filter only restaurant columns \n",
"fixed_columns =['Neighborhood'] + list(neighborhood_venues['VenueCategory'].unique())\n",
"venues_grouped = venues_grouped[fixed_columns]\n",
"\n",
"print(\"{} neighborhoods' venue category are shown in {} columns as below\".format(venues_grouped.shape[0],venues_grouped.shape[1]-1))\n",
"venues_grouped.head()"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Total Number of Venues</th>\n",
" <th>1st Most Common Restaurant</th>\n",
" <th>2nd Most Common Restaurant</th>\n",
" <th>3rd Most Common Restaurant</th>\n",
" <th>4th Most Common Restaurant</th>\n",
" <th>5th Most Common Restaurant</th>\n",
" <th>6th Most Common Restaurant</th>\n",
" <th>7th Most Common Restaurant</th>\n",
" <th>8th Most Common Restaurant</th>\n",
" <th>9th Most Common Restaurant</th>\n",
" <th>10th Most Common Restaurant</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>13 Septembrie</td>\n",
" <td>69</td>\n",
" <td>Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Café</td>\n",
" <td>Supermarket</td>\n",
" <td>Pub</td>\n",
" <td>Hotel</td>\n",
" <td>Lounge</td>\n",
" <td>Seafood Restaurant</td>\n",
" <td>Tea Room</td>\n",
" <td>Romanian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Aviației</td>\n",
" <td>86</td>\n",
" <td>Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Café</td>\n",
" <td>Hotel</td>\n",
" <td>Supermarket</td>\n",
" <td>Pizza Place</td>\n",
" <td>Clothing Store</td>\n",
" <td>Steakhouse</td>\n",
" <td>Burger Joint</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Berceni</td>\n",
" <td>27</td>\n",
" <td>Pizza Place</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Pharmacy</td>\n",
" <td>Grocery Store</td>\n",
" <td>Gym</td>\n",
" <td>Farmers Market</td>\n",
" <td>Eastern European Restaurant</td>\n",
" <td>Gym / Fitness Center</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Bucureștii Noi</td>\n",
" <td>11</td>\n",
" <td>Spa</td>\n",
" <td>Supermarket</td>\n",
" <td>Gym</td>\n",
" <td>Metro Station</td>\n",
" <td>Park</td>\n",
" <td>Gas Station</td>\n",
" <td>Mobile Phone Shop</td>\n",
" <td>Farmers Market</td>\n",
" <td>Korean Restaurant</td>\n",
" <td>Shop &amp; Service</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Băneasa</td>\n",
" <td>27</td>\n",
" <td>Hotel</td>\n",
" <td>Café</td>\n",
" <td>Restaurant</td>\n",
" <td>Romanian Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Doner Restaurant</td>\n",
" <td>Pizza Place</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Farmers Market</td>\n",
" <td>Food &amp; Drink Shop</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Total Number of Venues 1st Most Common Restaurant \\\n",
"0 13 Septembrie 69 Restaurant \n",
"1 Aviației 86 Restaurant \n",
"2 Berceni 27 Pizza Place \n",
"3 Bucureștii Noi 11 Spa \n",
"4 Băneasa 27 Hotel \n",
"\n",
" 2nd Most Common Restaurant 3rd Most Common Restaurant \\\n",
"0 Plaza Café \n",
"1 Bakery Café \n",
"2 Coffee Shop Pharmacy \n",
"3 Supermarket Gym \n",
"4 Café Restaurant \n",
"\n",
" 4th Most Common Restaurant 5th Most Common Restaurant \\\n",
"0 Supermarket Pub \n",
"1 Hotel Supermarket \n",
"2 Grocery Store Gym \n",
"3 Metro Station Park \n",
"4 Romanian Restaurant Italian Restaurant \n",
"\n",
" 6th Most Common Restaurant 7th Most Common Restaurant \\\n",
"0 Hotel Lounge \n",
"1 Pizza Place Clothing Store \n",
"2 Farmers Market Eastern European Restaurant \n",
"3 Gas Station Mobile Phone Shop \n",
"4 Doner Restaurant Pizza Place \n",
"\n",
" 8th Most Common Restaurant 9th Most Common Restaurant \\\n",
"0 Seafood Restaurant Tea Room \n",
"1 Steakhouse Burger Joint \n",
"2 Gym / Fitness Center Hotel \n",
"3 Farmers Market Korean Restaurant \n",
"4 Middle Eastern Restaurant Farmers Market \n",
"\n",
" 10th Most Common Restaurant \n",
"0 Romanian Restaurant \n",
"1 Coffee Shop \n",
"2 Italian Restaurant \n",
"3 Shop & Service \n",
"4 Food & Drink Shop "
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def return_most_common_venues(row, num_top_venues):\n",
" row_categories = row\n",
" row_categories_sorted = row_categories.sort_values(ascending=False)\n",
" \n",
" return row_categories_sorted.index.values[0:num_top_venues]\n",
"\n",
"num_top_venues = 10\n",
"\n",
"columns = ['Neighborhood','Total Number of Venues']\n",
"indicators = ['st', 'nd', 'rd']\n",
"# create columns according to number of top venues\n",
"\n",
"for ind in np.arange(num_top_venues):\n",
" try:\n",
" columns.append('{}{} Most Common Restaurant'.format(ind+1, indicators[ind]))\n",
" except:\n",
" columns.append('{}th Most Common Restaurant'.format(ind+1))\n",
"\n",
"# create a new dataframe\n",
"venues_most = pd.DataFrame(columns = columns)\n",
"\n",
"for ind in range(venues_grouped.shape[0]):\n",
" venues_most.loc[ind, 'Neighborhood'] = venues_grouped.iloc[ind].Neighborhood\n",
" venues_most.loc[ind, 'Total Number of Venues'] = venues_grouped.iloc[ind,1:].sum()\n",
" venues_most.iloc[ind, 2:] = return_most_common_venues(venues_grouped.iloc[ind, 1:], num_top_venues)\n",
"\n",
"venues_most.head()"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 720x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"import scipy.cluster.hierarchy as shc\n",
"\n",
"data = venues_grouped.iloc[:,3:]\n",
"plt.figure(figsize=(10, 6)) \n",
"plt.title('Hierarchical Clustering Dendrogram')\n",
"plt.xlabel('Neighborhoods')\n",
"plt.ylabel('Distance')\n",
"plt.axhline(y=20, c='k')\n",
"dend = shc.dendrogram(shc.linkage(data, method='ward'))"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Neighborhood</th>\n",
" <th>Sector</th>\n",
" <th>SectorPopulation</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>NeighborhoodCluster</th>\n",
" <th>1st Most Common Restaurant</th>\n",
" <th>2nd Most Common Restaurant</th>\n",
" <th>3rd Most Common Restaurant</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Aviației</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.485790</td>\n",
" <td>26.101219</td>\n",
" <td>0</td>\n",
" <td>Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Café</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Băneasa</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.494012</td>\n",
" <td>26.080358</td>\n",
" <td>2</td>\n",
" <td>Hotel</td>\n",
" <td>Café</td>\n",
" <td>Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Berceni</td>\n",
" <td>Sector 4</td>\n",
" <td>287,828</td>\n",
" <td>44.386430</td>\n",
" <td>26.128490</td>\n",
" <td>2</td>\n",
" <td>Pizza Place</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Pharmacy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Bucureștii Noi</td>\n",
" <td>Sector 1</td>\n",
" <td>225,454</td>\n",
" <td>44.480413</td>\n",
" <td>26.042807</td>\n",
" <td>2</td>\n",
" <td>Spa</td>\n",
" <td>Supermarket</td>\n",
" <td>Gym</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Centrul Civic</td>\n",
" <td>Sector 3</td>\n",
" <td>385,439</td>\n",
" <td>44.434300</td>\n",
" <td>26.094660</td>\n",
" <td>3</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Hotel</td>\n",
" <td>Theater</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Sector SectorPopulation Latitude Longitude \\\n",
"0 Aviației Sector 1 225,454 44.485790 26.101219 \n",
"1 Băneasa Sector 1 225,454 44.494012 26.080358 \n",
"2 Berceni Sector 4 287,828 44.386430 26.128490 \n",
"3 Bucureștii Noi Sector 1 225,454 44.480413 26.042807 \n",
"4 Centrul Civic Sector 3 385,439 44.434300 26.094660 \n",
"\n",
" NeighborhoodCluster 1st Most Common Restaurant 2nd Most Common Restaurant \\\n",
"0 0 Restaurant Bakery \n",
"1 2 Hotel Café \n",
"2 2 Pizza Place Coffee Shop \n",
"3 2 Spa Supermarket \n",
"4 3 Coffee Shop Hotel \n",
"\n",
" 3rd Most Common Restaurant \n",
"0 Café \n",
"1 Restaurant \n",
"2 Pharmacy \n",
"3 Gym \n",
"4 Theater "
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"from sklearn.cluster import AgglomerativeClustering\n",
"\n",
"kclusters= 6\n",
"cluster = AgglomerativeClustering(n_clusters=kclusters, affinity='euclidean', linkage='ward') \n",
"clusterresult = cluster.fit_predict(data)\n",
"\n",
"venues_grouped['NeighborhoodCluster'] = clusterresult\n",
"venues_cluster= df_neighborhood.merge(venues_grouped[['Neighborhood','NeighborhoodCluster']])\n",
"venues_cluster =venues_cluster.merge(venues_most[['Neighborhood','1st Most Common Restaurant','2nd Most Common Restaurant','3rd Most Common Restaurant']])\n",
"venues_cluster.head()"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2IiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNiA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDQuNDM2MTQxNCwyNi4xMDI3MjAyXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpvb206IDExLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXllcnM6IFtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgdGlsZV9sYXllcl84NTEyYTllMWUxMjI0Y2Q0YTYzOWM2M2U3YmQzNGFjZiA9IEwudGlsZUxheWVyKAogICAgICAgICAgICAgICAgJ2h0dHBzOi8ve3N9LnRpbGUub3BlbnN0cmVldG1hcC5vcmcve3p9L3t4fS97eX0ucG5nJywKICAgICAgICAgICAgICAgIHsKICAiYXR0cmlidXRpb24iOiBudWxsLAogICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAibWF4Wm9vbSI6IDE4LAogICJtaW5ab29tIjogMSwKICAibm9XcmFwIjogZmFsc2UsCiAgInN1YmRvbWFpbnMiOiAiYWJjIgp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTkxMDNkOGFlNWQ3NGIwNmI3NjkwMjQ3YzI4MDAwMGYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40ODU3ODk1LDI2LjEwMTIxOTQ5OTk5OTk5Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmYwMDAwIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84MDU4MDMxMDllNWM0NjQwYTQ3ZjNiMzdkZWIyODBhYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80NGI4MzBlNjAwMGI0YTc2YTk1MWZhMjUyNzQ3NGFkNSA9ICQoJzxkaXYgaWQ9Imh0bWxfNDRiODMwZTYwMDBiNGE3NmE5NTFmYTI1Mjc0NzRhZDUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkF2aWHIm2llaSAtIENsdXN0ZXIgMCBTZWN0b3IgMSAyMjUsNDU0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84MDU4MDMxMDllNWM0NjQwYTQ3ZjNiMzdkZWIyODBhYS5zZXRDb250ZW50KGh0bWxfNDRiODMwZTYwMDBiNGE3NmE5NTFmYTI1Mjc0NzRhZDUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTkxMDNkOGFlNWQ3NGIwNmI3NjkwMjQ3YzI4MDAwMGYuYmluZFBvcHVwKHBvcHVwXzgwNTgwMzEwOWU1YzQ2NDBhNDdmM2IzN2RlYjI4MGFhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JkYmE3M2U3MzYwYTQzMGU4ZDlmZDA1NmQ3M2Q5OTcwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDk0MDEyMzM5ODc5MTU2LDI2LjA4MDM1ODQ2NTAwNTIyNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMTk5NmYzIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzE5OTZmMyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mM2M4ZDU1Y2E0MmU0NTQ5YTMyODc5M2E3MjBkMjdiZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kYWIxMGZiNTk2MDk0MGU3OGQ4ZDg4YWEyOWY0ZTE1MCA9ICQoJzxkaXYgaWQ9Imh0bWxfZGFiMTBmYjU5NjA5NDBlNzhkOGQ4OGFhMjlmNGUxNTAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkLEg25lYXNhIC0gQ2x1c3RlciAyIFNlY3RvciAxIDIyNSw0NTQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2YzYzhkNTVjYTQyZTQ1NDlhMzI4NzkzYTcyMGQyN2JkLnNldENvbnRlbnQoaHRtbF9kYWIxMGZiNTk2MDk0MGU3OGQ4ZDg4YWEyOWY0ZTE1MCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iZGJhNzNlNzM2MGE0MzBlOGQ5ZmQwNTZkNzNkOTk3MC5iaW5kUG9wdXAocG9wdXBfZjNjOGQ1NWNhNDJlNDU0OWEzMjg3OTNhNzIwZDI3YmQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjIxM2Y3Y2I2MGJlNGU0YjkzZWZmNWFlNjcyYzZkNzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC4zODY0Mjk5OTk0MjMxMTUsMjYuMTI4NDkwMDI2Njg5MTI1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg5NGYwOTFjODE0NDQ3YjJhZTU3OWVkOTk3NjBkZjcwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2UxYzVhYjRmZDhmMzRmMzZiYmFiZjIyOTJlMDlhZTNmID0gJCgnPGRpdiBpZD0iaHRtbF9lMWM1YWI0ZmQ4ZjM0ZjM2YmJhYmYyMjkyZTA5YWUzZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVyY2VuaSAtIENsdXN0ZXIgMiBTZWN0b3IgNCAyODcsODI4PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84OTRmMDkxYzgxNDQ0N2IyYWU1NzllZDk5NzYwZGY3MC5zZXRDb250ZW50KGh0bWxfZTFjNWFiNGZkOGYzNGYzNmJiYWJmMjI5MmUwOWFlM2YpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjIxM2Y3Y2I2MGJlNGU0YjkzZWZmNWFlNjcyYzZkNzcuYmluZFBvcHVwKHBvcHVwXzg5NGYwOTFjODE0NDQ3YjJhZTU3OWVkOTk3NjBkZjcwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzg3MjI1NjA0YTkwZDQ5NGNhZTFkYWY4MmE1YmZhY2RjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDgwNDEyOTU5NTA1NzUsMjYuMDQyODA2NTYxMjcxMjE3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk4NDU0YWMyNDhiMjRlNDBhNGY4MDUzYmM1ZDg0MGNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg0Mjg3ZTZiYmZiNjRiYWViMmMxZDc2NzAwMTNmMTZjID0gJCgnPGRpdiBpZD0iaHRtbF84NDI4N2U2YmJmYjY0YmFlYjJjMWQ3NjcwMDEzZjE2YyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVjdXJlyJl0aWkgTm9pIC0gQ2x1c3RlciAyIFNlY3RvciAxIDIyNSw0NTQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk4NDU0YWMyNDhiMjRlNDBhNGY4MDUzYmM1ZDg0MGNkLnNldENvbnRlbnQoaHRtbF84NDI4N2U2YmJmYjY0YmFlYjJjMWQ3NjcwMDEzZjE2Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84NzIyNTYwNGE5MGQ0OTRjYWUxZGFmODJhNWJmYWNkYy5iaW5kUG9wdXAocG9wdXBfOTg0NTRhYzI0OGIyNGU0MGE0ZjgwNTNiYzVkODQwY2QpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGFjZWYwMzE3ZDBmNDU0M2FhZGYyNDliY2RhYzI5MTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MzQzMDAwMDAwMDAwNjQsMjYuMDk0NjYwMDAwMDAwMDMzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM0ZGYzY2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjNGRmM2NlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzlkZjU1MTJhOGNhYTQ0Y2Q4NGIyN2QwNDEyMzEzNjdkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U0YjIyNWI3NjNlYTQxMjdiYmI3NTBiYzQ3OGEzMDM0ID0gJCgnPGRpdiBpZD0iaHRtbF9lNGIyMjViNzYzZWE0MTI3YmJiNzUwYmM0NzhhMzAzNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VudHJ1bCBDaXZpYyAtIENsdXN0ZXIgMyBTZWN0b3IgMyAzODUsNDM5PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85ZGY1NTEyYThjYWE0NGNkODRiMjdkMDQxMjMxMzY3ZC5zZXRDb250ZW50KGh0bWxfZTRiMjI1Yjc2M2VhNDEyN2JiYjc1MGJjNDc4YTMwMzQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOGFjZWYwMzE3ZDBmNDU0M2FhZGYyNDliY2RhYzI5MTcuYmluZFBvcHVwKHBvcHVwXzlkZjU1MTJhOGNhYTQ0Y2Q4NGIyN2QwNDEyMzEzNjdkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNmZDY3NDY1NDkyMTRmMTNhNmRmYzgzNmMzM2VlYTI0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDc5NDAwNTk2OTEzNjU2LDI2LjE2NjUzNjgwOTk0NzQ0XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk5NmQ0Zjg4ZWU4YjQ2N2U4YzkxMjcyMjJjNDQ4NjEyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhmMTIwMDQxNzVjYTQ3M2Q4NDZjZTEzYzdkNjRjNTMyID0gJCgnPGRpdiBpZD0iaHRtbF84ZjEyMDA0MTc1Y2E0NzNkODQ2Y2UxM2M3ZDY0YzUzMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q29sZW50aW5hIC0gQ2x1c3RlciAyIFNlY3RvciAyIDM0NSwzNzA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk5NmQ0Zjg4ZWU4YjQ2N2U4YzkxMjcyMjJjNDQ4NjEyLnNldENvbnRlbnQoaHRtbF84ZjEyMDA0MTc1Y2E0NzNkODQ2Y2UxM2M3ZDY0YzUzMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zZmQ2NzQ2NTQ5MjE0ZjEzYTZkZmM4MzZjMzNlZWEyNC5iaW5kUG9wdXAocG9wdXBfOTk2ZDRmODhlZThiNDY3ZThjOTEyNzIyMmM0NDg2MTIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZjFjNzA5NTViZDUwNGRhMzg4ODcyZmFjOGQyN2IxYTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MzA2OTAwMDAwMDAwMywyNi4wNzM1MTAwMDAwMDAwNTZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmOTY0ZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjk2NGYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDRhZjQ3NDYwMWQwNDYzMjg0M2QwNWVlNGEyYjA0YjggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDdkMmIzNGQyNTM2NGExMTgyNjIxYTQ1ODgyOTEwNzQgPSAkKCc8ZGl2IGlkPSJodG1sXzQ3ZDJiMzRkMjUzNjRhMTE4MjYyMWE0NTg4MjkxMDc0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db3Ryb2NlbmkgLSBDbHVzdGVyIDUgU2VjdG9yIDUgMjcxLDU3NTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDRhZjQ3NDYwMWQwNDYzMjg0M2QwNWVlNGEyYjA0Yjguc2V0Q29udGVudChodG1sXzQ3ZDJiMzRkMjUzNjRhMTE4MjYyMWE0NTg4MjkxMDc0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YxYzcwOTU1YmQ1MDRkYTM4ODg3MmZhYzhkMjdiMWE5LmJpbmRQb3B1cChwb3B1cF80NGFmNDc0NjAxZDA0NjMyODQzZDA1ZWU0YTJiMDRiOCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yMjVmNWZjYTE0MWE0YTI0OTM3OWMxNGU0NzM3ZWYxMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ1Mjc2MDAwMDAwMDA3LDI2LjA0Mzg5MDAwMDAwMDAzM10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMTk5NmYzIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzE5OTZmMyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mYmNhZjdjM2FiZGU0NjUxYmZmMDExNjQxOGU1MGQ3OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iZjFhZWU2OTY3ZDM0MTIxYmZiZmMyYjVhYzhkNzYyMiA9ICQoJzxkaXYgaWQ9Imh0bWxfYmYxYWVlNjk2N2QzNDEyMWJmYmZjMmI1YWM4ZDc2MjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNyw6JuZ2HImWkgLSBDbHVzdGVyIDIgU2VjdG9yIDYgMzY3LDc2MDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmJjYWY3YzNhYmRlNDY1MWJmZjAxMTY0MThlNTBkNzkuc2V0Q29udGVudChodG1sX2JmMWFlZTY5NjdkMzQxMjFiZmJmYzJiNWFjOGQ3NjIyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzIyNWY1ZmNhMTQxYTRhMjQ5Mzc5YzE0ZTQ3MzdlZjEwLmJpbmRQb3B1cChwb3B1cF9mYmNhZjdjM2FiZGU0NjUxYmZmMDExNjQxOGU1MGQ3OSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wOWUwM2IxOTY0MmE0YmQ1OWRjZmI5ZmI3OWE0YzI1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQxNzIzOTQwMTY1ODQ5LDI2LjA1NzI4NTE4MDUxOTY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U3MDY0MmJkODZiNDQ3N2Q4NjI4NjFmZjRiM2FjZDk5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VjYmUwN2Q0YWE0ODRkMTc5ZjA3OGUwM2MxODY3NTExID0gJCgnPGRpdiBpZD0iaHRtbF9lY2JlMDdkNGFhNDg0ZDE3OWYwNzhlMDNjMTg2NzUxMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RMSDbcSDcm9haWEgLSBDbHVzdGVyIDIgU2VjdG9yIDEgMjI1LDQ1NDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTcwNjQyYmQ4NmI0NDc3ZDg2Mjg2MWZmNGIzYWNkOTkuc2V0Q29udGVudChodG1sX2VjYmUwN2Q0YWE0ODRkMTc5ZjA3OGUwM2MxODY3NTExKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzA5ZTAzYjE5NjQyYTRiZDU5ZGNmYjlmYjc5YTRjMjU2LmJpbmRQb3B1cChwb3B1cF9lNzA2NDJiZDg2YjQ0NzdkODYyODYxZmY0YjNhY2Q5OSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYTI3OTZhMTFjOTI0MDA4OGQ5MmMxZjBkNjRmZWRmOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMjk4MTg2MjUwODM2LDI2LjA2OTU5MzA1MDM4MDY3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmY5NjRmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmOTY0ZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zNTUwNDc0MzI0YTg0Yzg2OGJlMDljNWI0MGI0MzRlNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yNDgxNWY1NGVhYzk0MjliYTlhN2RlMTc4MTI3MWE0MSA9ICQoJzxkaXYgaWQ9Imh0bWxfMjQ4MTVmNTRlYWM5NDI5YmE5YTdkZTE3ODEyNzFhNDEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlYWx1bCBTcGlyaWkgLSBDbHVzdGVyIDUgU2VjdG9yIDUgMjcxLDU3NTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzU1MDQ3NDMyNGE4NGM4NjhiZTA5YzViNDBiNDM0ZTUuc2V0Q29udGVudChodG1sXzI0ODE1ZjU0ZWFjOTQyOWJhOWE3ZGUxNzgxMjcxYTQxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2JhMjc5NmExMWM5MjQwMDg4ZDkyYzFmMGQ2NGZlZGY5LmJpbmRQb3B1cChwb3B1cF8zNTUwNDc0MzI0YTg0Yzg2OGJlMDljNWI0MGI0MzRlNSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hZTIzYzNkYWU5N2Q0NzE2OGMyODhhZWZmNGE0OGMyNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ1OTY1MDk3NTcxMjA1LDI2LjA5MzcxMDc4NTk3NTI1NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODAwMGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82NDcyNWU2NDc5MzQ0MzhhOGY1ZGI4MTMyNjdjYjRmMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81N2E2ODAzYjM1MWI0YmJhOTE4MjYwYjNlOWI0ZDRjOSA9ICQoJzxkaXYgaWQ9Imh0bWxfNTdhNjgwM2IzNTFiNGJiYTkxODI2MGIzZTliNGQ0YzkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcm9iYW7Im2kgLSBDbHVzdGVyIDEgU2VjdG9yIDEgMjI1LDQ1NDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjQ3MjVlNjQ3OTM0NDM4YThmNWRiODEzMjY3Y2I0ZjIuc2V0Q29udGVudChodG1sXzU3YTY4MDNiMzUxYjRiYmE5MTgyNjBiM2U5YjRkNGM5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FlMjNjM2RhZTk3ZDQ3MTY4YzI4OGFlZmY0YTQ4YzI2LmJpbmRQb3B1cChwb3B1cF82NDcyNWU2NDc5MzQ0MzhhOGY1ZGI4MTMyNjdjYjRmMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zOGYzZjJhY2I2NTA0MzZhYWNhM2ZlN2VhNWE5NjczNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMDA5MDAwMDAwMDA3LDI2LjEzOTQ0MDAwMDAwMDAzNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjYjJmMzk2IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2IyZjM5NiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mYzlmZjEyZDFjYWU0MzNlYWI4MTIxODI3MjFhODIzMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zMmE1MDI1YmY2NmQ0NTRjYmVkYjQ0MjM5MzU5MGI2MCA9ICQoJzxkaXYgaWQ9Imh0bWxfMzJhNTAyNWJmNjZkNDU0Y2JlZGI0NDIzOTM1OTBiNjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRyaXN0b3IgLSBDbHVzdGVyIDQgU2VjdG9yIDMgMzg1LDQzOTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmM5ZmYxMmQxY2FlNDMzZWFiODEyMTgyNzIxYTgyMzMuc2V0Q29udGVudChodG1sXzMyYTUwMjViZjY2ZDQ1NGNiZWRiNDQyMzkzNTkwYjYwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzM4ZjNmMmFjYjY1MDQzNmFhY2EzZmU3ZWE1YTk2NzM1LmJpbmRQb3B1cChwb3B1cF9mYzlmZjEyZDFjYWU0MzNlYWI4MTIxODI3MjFhODIzMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80YzkxYWIwNWEwYmM0YmM0ODRiNDA3N2Q3MGY2MmQ2OSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMjEyMDAwMDAwMDA2NCwyNi4wMzM5NzAwMDAwMDAwNjhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2IyZjM5NiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNiMmYzOTYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTdhZjhkZmIxYjg0NGU5Nzg4MTY2MzZlNGUxODBhOWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2UwZWIwNWUxOWJiNGYxYjg5MmI3YTJjODU5MTRjZTYgPSAkKCc8ZGl2IGlkPSJodG1sX2NlMGViMDVlMTliYjRmMWI4OTJiN2EyYzg1OTE0Y2U2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EcnVtdWwgVGFiZXJlaSAtIENsdXN0ZXIgNCBTZWN0b3IgNiAzNjcsNzYwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81N2FmOGRmYjFiODQ0ZTk3ODgxNjYzNmU0ZTE4MGE5Yy5zZXRDb250ZW50KGh0bWxfY2UwZWIwNWUxOWJiNGYxYjg5MmI3YTJjODU5MTRjZTYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNGM5MWFiMDVhMGJjNGJjNDg0YjQwNzdkNzBmNjJkNjkuYmluZFBvcHVwKHBvcHVwXzU3YWY4ZGZiMWI4NDRlOTc4ODE2NjM2ZTRlMTgwYTljKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RhMTAwMDU2ZDBiYzQxODhhNmM2OTdmNDRhNjE2NGI0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDI0MDk2MTU1NTMwODI2LDI2LjEyMzY2MjM5OTc3NzQ2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzllNGM2N2JjMjNjNTRjNTk4ZmEyYmQ2M2JmMjVhZWJmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2NkNDljNzQxMjUyMzQwZDQ5YjNlMDQzZjE5ODBiOTgzID0gJCgnPGRpdiBpZD0iaHRtbF9jZDQ5Yzc0MTI1MjM0MGQ0OWIzZTA0M2YxOTgwYjk4MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RHVkZciZdGkgLSBDbHVzdGVyIDAgU2VjdG9yIDMgMzg1LDQzOTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOWU0YzY3YmMyM2M1NGM1OThmYTJiZDYzYmYyNWFlYmYuc2V0Q29udGVudChodG1sX2NkNDljNzQxMjUyMzQwZDQ5YjNlMDQzZjE5ODBiOTgzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RhMTAwMDU2ZDBiYzQxODhhNmM2OTdmNDRhNjE2NGI0LmJpbmRQb3B1cChwb3B1cF85ZTRjNjdiYzIzYzU0YzU5OGZhMmJkNjNiZjI1YWViZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iN2E3YTc5MTgzMWE0ZjZiYmY0NzE3ZmUzMTQ4ZjNjMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQxMjg2OTU4ODA4Nzg4LDI2LjA3MzQyNzVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzE5OTZmMyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMxOTk2ZjMiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzhiMmRiODk2Y2Q1NDMzYWIyOTkzN2QzMjM4NTgwZmIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDQxZmE1NDFjYjU3NDhiYjliNTY4YjhmMzk0MjQzOTAgPSAkKCc8ZGl2IGlkPSJodG1sXzQ0MWZhNTQxY2I1NzQ4YmI5YjU2OGI4ZjM5NDI0MzkwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5GZXJlbnRhcmkgLSBDbHVzdGVyIDIgU2VjdG9yIDUgMjcxLDU3NTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzhiMmRiODk2Y2Q1NDMzYWIyOTkzN2QzMjM4NTgwZmIuc2V0Q29udGVudChodG1sXzQ0MWZhNTQxY2I1NzQ4YmI5YjU2OGI4ZjM5NDI0MzkwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I3YTdhNzkxODMxYTRmNmJiZjQ3MTdmZTMxNDhmM2MyLmJpbmRQb3B1cChwb3B1cF8zOGIyZGI4OTZjZDU0MzNhYjI5OTM3ZDMyMzg1ODBmYik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82OTVkY2QzMTE3MDA0MTYzYmU1YjlhODg1N2QzNjhjNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ3NjMwODE5MzY5ODI5LDI2LjEwMzI4ODY5OTY2ODI3Nl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmYwMDAwIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83YzJlMzIxNDI1OGY0MzljOGM4ZGZhNmM3ZDVmMWQ5NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NjI2NzZlNzUwODE0NDczYTdlZWYzYzQyMTMzYTBmOCA9ICQoJzxkaXYgaWQ9Imh0bWxfNjYyNjc2ZTc1MDgxNDQ3M2E3ZWVmM2M0MjEzM2EwZjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZsb3JlYXNjYSAtIENsdXN0ZXIgMCBTZWN0b3IgMiAzNDUsMzcwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83YzJlMzIxNDI1OGY0MzljOGM4ZGZhNmM3ZDVmMWQ5NS5zZXRDb250ZW50KGh0bWxfNjYyNjc2ZTc1MDgxNDQ3M2E3ZWVmM2M0MjEzM2EwZjgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjk1ZGNkMzExNzAwNDE2M2JlNWI5YTg4NTdkMzY4YzQuYmluZFBvcHVwKHBvcHVwXzdjMmUzMjE0MjU4ZjQzOWM4YzhkZmE2YzdkNWYxZDk1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2MyMzliOTFkN2QxNzRlOGE4ODZhYzg2N2ExZmE3ZTI1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQ5MTc1NjUxOTI0MjEsMjYuMTY2NTIyMjc4NTg1NTQzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ2MjM4ZjZiNzA0ZDQ1ODdiMTlhZTliMjRjNTFlOGNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE3NzYxYzBkMDcwNTRlYTQ4OTBjMmJjNTlmNjM2YmZiID0gJCgnPGRpdiBpZD0iaHRtbF8xNzc2MWMwZDA3MDU0ZWE0ODkwYzJiYzU5ZjYzNmJmYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RnVuZGVuaSAtIENsdXN0ZXIgMiBTZWN0b3IgMiAzNDUsMzcwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NjIzOGY2YjcwNGQ0NTg3YjE5YWU5YjI0YzUxZThjZC5zZXRDb250ZW50KGh0bWxfMTc3NjFjMGQwNzA1NGVhNDg5MGMyYmM1OWY2MzZiZmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzIzOWI5MWQ3ZDE3NGU4YTg4NmFjODY3YTFmYTdlMjUuYmluZFBvcHVwKHBvcHVwXzQ2MjM4ZjZiNzA0ZDQ1ODdiMTlhZTliMjRjNTFlOGNkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ2MWJiZWZiYzkyZDRiZGU4ZTYzOGMzZjRhYTIyZmU0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDE4MzYwMDAwMDAwMDY0LDI2LjA1ODYwMDAwMDAwMDA3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ViYzY3MjljM2UwZTRkZGE5Y2Y1YjBlYzgwNWYwMjY2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE1ODI3NTBhOGRmODQ2MGVhZjQ5ZDU0Mzg1YzM4MTA2ID0gJCgnPGRpdiBpZD0iaHRtbF8xNTgyNzUwYThkZjg0NjBlYWY0OWQ1NDM4NWMzODEwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2hlbmNlYSAtIENsdXN0ZXIgMiBTZWN0b3IgNiAzNjcsNzYwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lYmM2NzI5YzNlMGU0ZGRhOWNmNWIwZWM4MDVmMDI2Ni5zZXRDb250ZW50KGh0bWxfMTU4Mjc1MGE4ZGY4NDYwZWFmNDlkNTQzODVjMzgxMDYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDYxYmJlZmJjOTJkNGJkZThlNjM4YzNmNGFhMjJmZTQuYmluZFBvcHVwKHBvcHVwX2ViYzY3MjljM2UwZTRkZGE5Y2Y1YjBlYzgwNWYwMjY2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2JiMTIzOTU0ZjRmZjQ5MmFhZjUzZjcxYjc3ZGQyN2QyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDcwMDgzMzU5ODA0NTcsMjYuMDAyNTEyNDU2MzkxNzAzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU3Y2E3YThkMWEzZDRkYzk4NDcxOTkxYTM3YmFmODRiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdjMjQyYWZmNzQ0YzQxOWY4MDE3MTYxNzBjNTRjMWJkID0gJCgnPGRpdiBpZD0iaHRtbF83YzI0MmFmZjc0NGM0MTlmODAxNzE2MTcwYzU0YzFiZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2l1bGXImXRpIC0gQ2x1c3RlciAyIFNlY3RvciAxIDIyNSw0NTQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU3Y2E3YThkMWEzZDRkYzk4NDcxOTkxYTM3YmFmODRiLnNldENvbnRlbnQoaHRtbF83YzI0MmFmZjc0NGM0MTlmODAxNzE2MTcwYzU0YzFiZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iYjEyMzk1NGY0ZmY0OTJhYWY1M2Y3MWI3N2RkMjdkMi5iaW5kUG9wdXAocG9wdXBfNTdjYTdhOGQxYTNkNGRjOTg0NzE5OTFhMzdiYWY4NGIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfN2JkNjE3ZmIzMDgwNDBiYWE2NWRlY2I1YTdlMTJjYzggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NDc3NTAwMDAwMDAwNCwyNi4wNzUzOTAwMDAwMDAwMjddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGZlZDM4NTBkN2UxNDc4YTk4YzAxMTczNDEwYzIxM2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmFiNDAzMjExZDY5NDBjOThlNTI5OWVhYzU3YWY2NTMgPSAkKCc8ZGl2IGlkPSJodG1sX2JhYjQwMzIxMWQ2OTQwYzk4ZTUyOTllYWM1N2FmNjUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Hcml2acibYSAtIENsdXN0ZXIgMSBTZWN0b3IgMSAyMjUsNDU0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84ZmVkMzg1MGQ3ZTE0NzhhOThjMDExNzM0MTBjMjEzZC5zZXRDb250ZW50KGh0bWxfYmFiNDAzMjExZDY5NDBjOThlNTI5OWVhYzU3YWY2NTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfN2JkNjE3ZmIzMDgwNDBiYWE2NWRlY2I1YTdlMTJjYzguYmluZFBvcHVwKHBvcHVwXzhmZWQzODUwZDdlMTQ3OGE5OGMwMTE3MzQxMGMyMTNkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YyOTNiNThjNzA1ZjQzY2Q5YTg4ZjY5NDdmZjdhMGQ0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQwMzc1Mzg2OTY0MDQsMjYuMTM0NDUyMDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2IyZjM5NiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNiMmYzOTYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTQzNDM3OTdiNjcwNDMxNjg1NWNiMzQ1ZjgxNmQ2NjIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjAyMGIzODkzODU4NGUxMTkyMDJiODg0YWVjNTUyODAgPSAkKCc8ZGl2IGlkPSJodG1sXzIwMjBiMzg5Mzg1ODRlMTE5MjAyYjg4NGFlYzU1MjgwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5JYW5jdWx1aSAtIENsdXN0ZXIgNCBTZWN0b3IgMiAzNDUsMzcwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lNDM0Mzc5N2I2NzA0MzE2ODU1Y2IzNDVmODE2ZDY2Mi5zZXRDb250ZW50KGh0bWxfMjAyMGIzODkzODU4NGUxMTkyMDJiODg0YWVjNTUyODApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZjI5M2I1OGM3MDVmNDNjZDlhODhmNjk0N2ZmN2EwZDQuYmluZFBvcHVwKHBvcHVwX2U0MzQzNzk3YjY3MDQzMTY4NTVjYjM0NWY4MTZkNjYyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzg2MzAwNGUyN2Q2NTRhYTQ4MzRhZTBmYmFhNDIyMjhiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDMyMTU1MzQzOTUxMywyNi4xMDQwNTY2MjM0MzM5NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjNGRmM2NlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzRkZjNjZSIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iMjY0ZWMzMjVjZjE0NjA3OWI5YmJhZDRjMzVlNzZiZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81ZTUzMmE5ZWE2NjA0NTRjOGZlZDAyNzNhMDhlNzY1YiA9ICQoJzxkaXYgaWQ9Imh0bWxfNWU1MzJhOWVhNjYwNDU0YzhmZWQwMjczYTA4ZTc2NWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxpcHNjYW5pIC0gQ2x1c3RlciAzIFNlY3RvciAzIDM4NSw0Mzk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2IyNjRlYzMyNWNmMTQ2MDc5YjliYmFkNGMzNWU3NmJkLnNldENvbnRlbnQoaHRtbF81ZTUzMmE5ZWE2NjA0NTRjOGZlZDAyNzNhMDhlNzY1Yik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84NjMwMDRlMjdkNjU0YWE0ODM0YWUwZmJhYTQyMjI4Yi5iaW5kUG9wdXAocG9wdXBfYjI2NGVjMzI1Y2YxNDYwNzliOWJiYWQ0YzM1ZTc2YmQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfM2E4NTMwYTllNjc1NDA1MWFhYzNiNzBhZWJkNWI0YzIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MzQyOTAwMDAwMDAwMywyNi4xMDI5ODAwMDAwMDAwNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjNGRmM2NlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzRkZjNjZSIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85MzVlYWQ2MDJhOWY0OWE2OGVlNTkzYWZkMTQ3YTdkMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80ZTNmZDIzYzY3MzA0NDViODA0NTJkYTA3MTk4ODA4MCA9ICQoJzxkaXYgaWQ9Imh0bWxfNGUzZmQyM2M2NzMwNDQ1YjgwNDUyZGEwNzE5ODgwODAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbGl0YXJpIC0gQ2x1c3RlciAzIFNlY3RvciA2IDM2Nyw3NjA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzkzNWVhZDYwMmE5ZjQ5YTY4ZWU1OTNhZmQxNDdhN2QwLnNldENvbnRlbnQoaHRtbF80ZTNmZDIzYzY3MzA0NDViODA0NTJkYTA3MTk4ODA4MCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8zYTg1MzBhOWU2NzU0MDUxYWFjM2I3MGFlYmQ1YjRjMi5iaW5kUG9wdXAocG9wdXBfOTM1ZWFkNjAyYTlmNDlhNjhlZTU5M2FmZDE0N2E3ZDApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNGFjYzBmZGJkMDVkNGY5YjkyYzUwZjU0YTczYzM0NmUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MTI0MDM1LDI2LjEyMzQwMjI1MDAwMDAxNl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjYjJmMzk2IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2IyZjM5NiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82NTc0OTgyNWU0YzY0NDdjYjRmODM4MTYyNWUxMWE1OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZDMzZTBiZGIzYmE0ZWFmYTQzMDg3OTI2NjAwNzNhMSA9ICQoJzxkaXYgaWQ9Imh0bWxfZGQzM2UwYmRiM2JhNGVhZmE0MzA4NzkyNjYwMDczYTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1vyJlpbG9yIC0gQ2x1c3RlciA0IFNlY3RvciAyIDM0NSwzNzA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY1NzQ5ODI1ZTRjNjQ0N2NiNGY4MzgxNjI1ZTExYTU5LnNldENvbnRlbnQoaHRtbF9kZDMzZTBiZGIzYmE0ZWFmYTQzMDg3OTI2NjAwNzNhMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80YWNjMGZkYmQwNWQ0ZjliOTJjNTBmNTRhNzNjMzQ2ZS5iaW5kUG9wdXAocG9wdXBfNjU3NDk4MjVlNGM2NDQ3Y2I0ZjgzODE2MjVlMTFhNTkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTdkOGYwYjEwMzRjNGI0NmJjZTQwMTdhMDlmNzVmMTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTE0NzAwMDAwMDAwMywyNi4xMjY0NzAwMDAwMDAwNF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjYjJmMzk2IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2IyZjM5NiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84MTQ5YTEzYzljYjM0ODM0YjMyMDhjOWJlY2ZmZjBhZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zYTMwNzkxYWQzYzc0N2EwODczZGZhZGUzMzRlZDM3NyA9ICQoJzxkaXYgaWQ9Imh0bWxfM2EzMDc5MWFkM2M3NDdhMDg3M2RmYWRlMzM0ZWQzNzciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk9ib3IgLSBDbHVzdGVyIDQgU2VjdG9yIDIgMzQ1LDM3MDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODE0OWExM2M5Y2IzNDgzNGIzMjA4YzliZWNmZmYwYWQuc2V0Q29udGVudChodG1sXzNhMzA3OTFhZDNjNzQ3YTA4NzNkZmFkZTMzNGVkMzc3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU3ZDhmMGIxMDM0YzRiNDZiY2U0MDE3YTA5Zjc1ZjE5LmJpbmRQb3B1cChwb3B1cF84MTQ5YTEzYzljYjM0ODM0YjMyMDhjOWJlY2ZmZjBhZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85ZThlNDc4NWJjZmQ0NzczYWNhMDU1OTY5ZjQwMzgxMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjUyOTEzNjAxNTE0NDkzNSwyNi4wNDc0NDA1NzMwMzU2OTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzE5OTZmMyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMxOTk2ZjMiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzEzMmY3OWUwNzliNDU0YjhiY2Q3Nzk3MmE3ZDdiNzEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjA5NmFmMGIzODYyNDBlYmIwZWVhZDkwZTc3NTU5MjUgPSAkKCc8ZGl2IGlkPSJodG1sX2IwOTZhZjBiMzg2MjQwZWJiMGVlYWQ5MGU3NzU1OTI1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5PZMSDaSAtIENsdXN0ZXIgMiBOb25lIE5vbmU8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2MxMzJmNzllMDc5YjQ1NGI4YmNkNzc5NzJhN2Q3YjcxLnNldENvbnRlbnQoaHRtbF9iMDk2YWYwYjM4NjI0MGViYjBlZWFkOTBlNzc1NTkyNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85ZThlNDc4NWJjZmQ0NzczYWNhMDU1OTY5ZjQwMzgxMy5iaW5kUG9wdXAocG9wdXBfYzEzMmY3OWUwNzliNDU0YjhiY2Q3Nzk3MmE3ZDdiNzEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjQzYjJjYzI4OGJmNDViYWE4M2M2NDUzMjkxOTJiN2UgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC4zOTA0NTg4NDUzMTI1LDI2LjEyOTEwMTQyMjYzMTgxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNiMmYzOTYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjYjJmMzk2IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FhNzNiNWMxZjA2YTQ5ZjU4OTMzZWY4OWY2NTZhYzYxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE3MmQwZGMwZGUyNDQ5NzJhNTNhNzkyNGU1ZDJhMDgzID0gJCgnPGRpdiBpZD0iaHRtbF8xNzJkMGRjMGRlMjQ0OTcyYTUzYTc5MjRlNWQyYTA4MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+T2x0ZW5pyJtlaSAtIENsdXN0ZXIgNCBTZWN0b3IgNCAyODcsODI4PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hYTczYjVjMWYwNmE0OWY1ODkzM2VmODlmNjU2YWM2MS5zZXRDb250ZW50KGh0bWxfMTcyZDBkYzBkZTI0NDk3MmE1M2E3OTI0ZTVkMmEwODMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjQzYjJjYzI4OGJmNDViYWE4M2M2NDUzMjkxOTJiN2UuYmluZFBvcHVwKHBvcHVwX2FhNzNiNWMxZjA2YTQ5ZjU4OTMzZWY4OWY2NTZhYzYxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdkMGU2ZDc4OTc1ZjQ1NDBhNDQ1MTcyNmQzMWIxOGYzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQxNTI4MjcxNzI4NjY0LDI2LjE5NDI0ODkwMjEwMDY2NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMTk5NmYzIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzE5OTZmMyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84NjkxM2NmNjE3ZDc0MTlhOTU3NGQyODJkMzViMjdhZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMDhhZDA1MWVlZTc0N2YwYTY4ZDg3OTUyZDBkNWI4ZiA9ICQoJzxkaXYgaWQ9Imh0bWxfYTA4YWQwNTFlZWU3NDdmMGE2OGQ4Nzk1MmQwZDViOGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhbnRlbGltb24gLSBDbHVzdGVyIDIgU2VjdG9yIDIgMzQ1LDM3MDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODY5MTNjZjYxN2Q3NDE5YTk1NzRkMjgyZDM1YjI3YWQuc2V0Q29udGVudChodG1sX2EwOGFkMDUxZWVlNzQ3ZjBhNjhkODc5NTJkMGQ1YjhmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdkMGU2ZDc4OTc1ZjQ1NDBhNDQ1MTcyNmQzMWIxOGYzLmJpbmRQb3B1cChwb3B1cF84NjkxM2NmNjE3ZDc0MTlhOTU3NGQyODJkMzViMjdhZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84OTNiYzg4Y2IxZWE0NzcxOGViNTBhYzAzM2EzOTVjOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ4NzE2MDEzNjUwMjQzLDI2LjExNDY3NzA4OTU3NjY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMxOTk2ZjMiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMTk5NmYzIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFiNzI0YTcxZWM3ODQ2ZmFiN2RjN2UzMTA3NjRmZmZkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzU1YmM2MjJmZjdiYjRjM2Q5M2JhODgyMzljYzRlYjI5ID0gJCgnPGRpdiBpZD0iaHRtbF81NWJjNjIyZmY3YmI0YzNkOTNiYTg4MjM5Y2M0ZWIyOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGlwZXJhIC0gQ2x1c3RlciAyIFNlY3RvciAxIDIyNSw0NTQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFiNzI0YTcxZWM3ODQ2ZmFiN2RjN2UzMTA3NjRmZmZkLnNldENvbnRlbnQoaHRtbF81NWJjNjIyZmY3YmI0YzNkOTNiYTg4MjM5Y2M0ZWIyOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84OTNiYzg4Y2IxZWE0NzcxOGViNTBhYzAzM2EzOTVjOS5iaW5kUG9wdXAocG9wdXBfMWI3MjRhNzFlYzc4NDZmYWI3ZGM3ZTMxMDc2NGZmZmQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTE1MmI1ZmZkYTNkNGVjNjk2MDczMjI0MDMzYjVhYWYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40Njk3MTA4NTYzMDI4NTQsMjYuMDkyODY2NTAwNzM1MDA2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM4MDAwZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjODAwMGZmIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc3N2NmZDA2ZTUyNDRjODRiMDU0NTI1NDk0MjEwYzRhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U0ZGFhYzkzNmExOTQ4ODc4NDgwYjUyYjQyNWZlZDFjID0gJCgnPGRpdiBpZD0iaHRtbF9lNGRhYWM5MzZhMTk0ODg3ODQ4MGI1MmI0MjVmZWQxYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UHJpbcSDdmVyaWkgLSBDbHVzdGVyIDEgU2VjdG9yIDEgMjI1LDQ1NDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzc3Y2ZkMDZlNTI0NGM4NGIwNTQ1MjU0OTQyMTBjNGEuc2V0Q29udGVudChodG1sX2U0ZGFhYzkzNmExOTQ4ODc4NDgwYjUyYjQyNWZlZDFjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2UxNTJiNWZmZGEzZDRlYzY5NjA3MzIyNDAzM2I1YWFmLmJpbmRQb3B1cChwb3B1cF83NzdjZmQwNmU1MjQ0Yzg0YjA1NDUyNTQ5NDIxMGM0YSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83NTg0OTE3ZDY0NDY0Yjg4YmM3ZWI5YTAxZDkzYWM4NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQyMzkzMjUwMDAwMDAxNCwyNi4wNjc4NTg3NDk5OTk5OTJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmOTY0ZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjk2NGYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzI5MTdjMzA4ODU2NGM0MzhlYTNkY2NlZGY0NWNlYmIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTJiOTVlZjg4ZmI3NDAxNGI1Mjk4YmU5ZWVjNDMwNTMgPSAkKCc8ZGl2IGlkPSJodG1sX2EyYjk1ZWY4OGZiNzQwMTRiNTI5OGJlOWVlYzQzMDUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Qcm9ncmVzdWwgLSBDbHVzdGVyIDUgTm9uZSBOb25lPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMjkxN2MzMDg4NTY0YzQzOGVhM2RjY2VkZjQ1Y2ViYi5zZXRDb250ZW50KGh0bWxfYTJiOTVlZjg4ZmI3NDAxNGI1Mjk4YmU5ZWVjNDMwNTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzU4NDkxN2Q2NDQ2NGI4OGJjN2ViOWEwMWQ5M2FjODcuYmluZFBvcHVwKHBvcHVwXzMyOTE3YzMwODg1NjRjNDM4ZWEzZGNjZWRmNDVjZWJiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwNDliMzQ5MTIyYzQ5ZWNiMTYxN2NhMTNjNmMzNjQ2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDA4NDgwMDAwMDAwMDU0LDI2LjA2NzMzMDAwMDAwMDAyN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMTk5NmYzIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzE5OTZmMyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81YzkyN2U2M2Q2MDE0Zjc2Yjc3MzA3ZGFhZjE0MmZmYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMGFiYzgxODM4M2M0Yjc0OGNlNTlkNjhkNWRjY2NhYSA9ICQoJzxkaXYgaWQ9Imh0bWxfZjBhYmM4MTgzODNjNGI3NDhjZTU5ZDY4ZDVkY2NjYWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJhaG92YSAtIENsdXN0ZXIgMiBTZWN0b3IgNSAyNzEsNTc1PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81YzkyN2U2M2Q2MDE0Zjc2Yjc3MzA3ZGFhZjE0MmZmYi5zZXRDb250ZW50KGh0bWxfZjBhYmM4MTgzODNjNGI3NDhjZTU5ZDY4ZDVkY2NjYWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjA0OWIzNDkxMjJjNDllY2IxNjE3Y2ExM2M2YzM2NDYuYmluZFBvcHVwKHBvcHVwXzVjOTI3ZTYzZDYwMTRmNzZiNzczMDdkYWFmMTQyZmZiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2VmNmIzMTNjYWQzZTRkNDJiOGE3M2FiMjY3YmFmMGM5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDQ2NjE2OTk5OTk5OTksMjYuMDU5NDcwNzQ5OTk5OTk2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNiMmYzOTYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjYjJmMzk2IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzY2ZWZjOTViMTc0ZjRhNDhiYTQ1MDQxMjcxODIxYTZjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzIwMzlkODcyNmFlYjQyODJiODIzZjZjMmFiM2Y4YmNkID0gJCgnPGRpdiBpZD0iaHRtbF8yMDM5ZDg3MjZhZWI0MjgyYjgyM2Y2YzJhYjNmOGJjZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UmVnaWUgLSBDbHVzdGVyIDQgU2VjdG9yIDYgMzY3LDc2MDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjZlZmM5NWIxNzRmNGE0OGJhNDUwNDEyNzE4MjFhNmMuc2V0Q29udGVudChodG1sXzIwMzlkODcyNmFlYjQyODJiODIzZjZjMmFiM2Y4YmNkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2VmNmIzMTNjYWQzZTRkNDJiOGE3M2FiMjY3YmFmMGM5LmJpbmRQb3B1cChwb3B1cF82NmVmYzk1YjE3NGY0YTQ4YmE0NTA0MTI3MTgyMWE2Yyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zYzY2MjRhMDA1YTY0NWUxYTYxYTg5YTE2ZjJlMmRhNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQ0MTYwODQ5OTk5OTk5NCwyNS45ODIzNzg5OTk5OTk5OTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzE5OTZmMyIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMxOTk2ZjMiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWQxYThmYzM0NWY1NDUyNjgyYWZlMGRkYjE3YTZhOTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGYxMTY2MGZiYWEyNDU2Y2IzMTgxY2IxMzlhMDRiZWYgPSAkKCc8ZGl2IGlkPSJodG1sX2RmMTE2NjBmYmFhMjQ1NmNiMzE4MWNiMTM5YTA0YmVmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaW5lcmV0dWx1aSAtIENsdXN0ZXIgMiBTZWN0b3IgNCAyODcsODI4PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lZDFhOGZjMzQ1ZjU0NTI2ODJhZmUwZGRiMTdhNmE5NC5zZXRDb250ZW50KGh0bWxfZGYxMTY2MGZiYWEyNDU2Y2IzMTgxY2IxMzlhMDRiZWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2M2NjI0YTAwNWE2NDVlMWE2MWE4OWExNmYyZTJkYTYuYmluZFBvcHVwKHBvcHVwX2VkMWE4ZmMzNDVmNTQ1MjY4MmFmZTBkZGIxN2E2YTk0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY2Mzc2MzNmZTgxYjQwNDJiMDQ4ZmU0MWE2MTYzOGE4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDI0OTk3Njc5NzgzMDQsMjYuMDgzMzMxMDI1OTgxMTY3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjk2NGYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmY5NjRmIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Q4OTM4ZTg3OTQ5MzRjYmE4NmRhNDA3NGEwNWFhMWE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Q4OTZhYjI5ZjMxOTQ4ZDBiMTI0NmRjM2IwMDI3ZWE2ID0gJCgnPGRpdiBpZD0iaHRtbF9kODk2YWIyOWYzMTk0OGQwYjEyNDZkYzNiMDAyN2VhNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTMgU2VwdGVtYnJpZSAtIENsdXN0ZXIgNSBTZWN0b3IgNSAyNzEsNTc1PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kODkzOGU4Nzk0OTM0Y2JhODZkYTQwNzRhMDVhYTFhNC5zZXRDb250ZW50KGh0bWxfZDg5NmFiMjlmMzE5NDhkMGIxMjQ2ZGMzYjAwMjdlYTYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjYzNzYzM2ZlODFiNDA0MmIwNDhmZTQxYTYxNjM4YTguYmluZFBvcHVwKHBvcHVwX2Q4OTM4ZTg3OTQ5MzRjYmE4NmRhNDA3NGEwNWFhMWE0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY2MGFhNTU4YTFlZTQ3ODViN2MwMTNkNDI4MDdkMzRjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuMzkwMjEwMDAwMDAwMDI1LDI2LjA5MjQ1MDAwMDAwMDA0Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjMTk5NmYzIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzE5OTZmMyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82ZTdkYjBlOWYwNmY0ZmRlOTcwZjE3ZTY4ZTg2ZDAxNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82MGYwZjQwYTMyMGU0YTg2OTAxZTM2ZmZjNTgyZmU1OSA9ICQoJzxkaXYgaWQ9Imh0bWxfNjBmMGY0MGEzMjBlNGE4NjkwMWUzNmZmYzU4MmZlNTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdpdXJnaXVsdWkgLSBDbHVzdGVyIDIgU2VjdG9yIDUgMjcxLDU3NTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNmU3ZGIwZTlmMDZmNGZkZTk3MGYxN2U2OGU4NmQwMTQuc2V0Q29udGVudChodG1sXzYwZjBmNDBhMzIwZTRhODY5MDFlMzZmZmM1ODJmZTU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzY2MGFhNTU4YTFlZTQ3ODViN2MwMTNkNDI4MDdkMzRjLmJpbmRQb3B1cChwb3B1cF82ZTdkYjBlOWYwNmY0ZmRlOTcwZjE3ZTY4ZTg2ZDAxNCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MWZiMmI1ZmM0ODM0MjZmYjdhNGNmOWY4MDM2MDk1MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQzNDI5MDAwMDAwMDAzLDI2LjEwMjk4MDAwMDAwMDA2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM0ZGYzY2UiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjNGRmM2NlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RhMTg4ZjU0MDEwNTQ0ZjE5MGE5NTNkMjE5OWNlMDgyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2FiNDlmZDRhMWExNjQ0YTFhZTUzMTRkMjYwNTc0MWRjID0gJCgnPGRpdiBpZD0iaHRtbF9hYjQ5ZmQ0YTFhMTY0NGExYWU1MzE0ZDI2MDU3NDFkYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGVpIC0gQ2x1c3RlciAzIFNlY3RvciAyIDM0NSwzNzA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RhMTg4ZjU0MDEwNTQ0ZjE5MGE5NTNkMjE5OWNlMDgyLnNldENvbnRlbnQoaHRtbF9hYjQ5ZmQ0YTFhMTY0NGExYWU1MzE0ZDI2MDU3NDFkYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82MWZiMmI1ZmM0ODM0MjZmYjdhNGNmOWY4MDM2MDk1My5iaW5kUG9wdXAocG9wdXBfZGExODhmNTQwMTA1NDRmMTkwYTk1M2QyMTk5Y2UwODIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjE0NTUzYWIwMjA0NDJiMzkxYjYxNWQ0NDI0YmFlZGIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40NTY4NTAwMDAwMDAwMywyNi4xMDA2NDAwMDAwMDAwNTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmY0MmY4ZjIxYThmNDJmNWJiNzI3NTBiZjZjNGQ4NzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjE0YzU1MWIxNjJiNDYwMWE4NDI0OTNkMmY2ZWI5NGQgPSAkKCc8ZGl2IGlkPSJodG1sXzIxNGM1NTFiMTYyYjQ2MDFhODQyNDkzZDJmNmViOTRkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaXRhbiAtIENsdXN0ZXIgMSBTZWN0b3IgMyAzODUsNDM5PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mZjQyZjhmMjFhOGY0MmY1YmI3Mjc1MGJmNmM0ZDg3Mi5zZXRDb250ZW50KGh0bWxfMjE0YzU1MWIxNjJiNDYwMWE4NDI0OTNkMmY2ZWI5NGQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjE0NTUzYWIwMjA0NDJiMzkxYjYxNWQ0NDI0YmFlZGIuYmluZFBvcHVwKHBvcHVwX2ZmNDJmOGYyMWE4ZjQyZjViYjcyNzUwYmY2YzRkODcyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIxYWQ1MjIxYmVkYjRhOTNhZDk5ODkyMzNiNTdkMWUxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDQuNDE1NTMwMDAwMDAwMDUsMjYuMTEzNTQwMDAwMDAwMDU3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNiMmYzOTYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjYjJmMzk2IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc4OGNhYTkyMmZiYTQzNmNhZTM4YjVmNjc2NDhiY2E4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQwODc2MWJiZmQyMjQ3YmM5OWEzZmFiNGE1ZDRlYjI4ID0gJCgnPGRpdiBpZD0iaHRtbF80MDg3NjFiYmZkMjI0N2JjOTlhM2ZhYjRhNWQ0ZWIyOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VsSDY8SDcmXImXRpIC0gQ2x1c3RlciA0IFNlY3RvciA0IDI4Nyw4Mjg8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc4OGNhYTkyMmZiYTQzNmNhZTM4YjVmNjc2NDhiY2E4LnNldENvbnRlbnQoaHRtbF80MDg3NjFiYmZkMjI0N2JjOTlhM2ZhYjRhNWQ0ZWIyOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yMWFkNTIyMWJlZGI0YTkzYWQ5OTg5MjMzYjU3ZDFlMS5iaW5kUG9wdXAocG9wdXBfNzg4Y2FhOTIyZmJhNDM2Y2FlMzhiNWY2NzY0OGJjYTgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTM5NmMzNjg0OTJlNGNkMmE2YWJkZjFjN2NlNjYxNTIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0NC40MjI3MzUwNDc0ODE5ODYsMjYuMTI0NDg4NDIyOTk4MzU4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk1NDAxYWUwNjg3MjQyNDJiNDI2ZTNlZTgwNWNkMWQ5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2QyOGIyNmUwZmRmOTQ5NzQ4YjFiMzgyOGYyNzlkODBjID0gJCgnPGRpdiBpZD0iaHRtbF9kMjhiMjZlMGZkZjk0OTc0OGIxYjM4MjhmMjc5ZDgwYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Vml0YW4gLSBDbHVzdGVyIDAgU2VjdG9yIDMgMzg1LDQzOTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTU0MDFhZTA2ODcyNDI0MmI0MjZlM2VlODA1Y2QxZDkuc2V0Q29udGVudChodG1sX2QyOGIyNmUwZmRmOTQ5NzQ4YjFiMzgyOGYyNzlkODBjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzUzOTZjMzY4NDkyZTRjZDJhNmFiZGYxYzdjZTY2MTUyLmJpbmRQb3B1cChwb3B1cF85NTQwMWFlMDY4NzI0MjQyYjQyNmUzZWU4MDVjZDFkOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAoKICAgICAgICAgICAgdmFyIG1hcmtlcl83MDYyNzg0YWZlNWM0OGNmYjMzMGI0ZGU1Nzg3ZGM4OCA9IEwubWFya2VyKAogICAgICAgICAgICAgICAgWzQ0LjQzNjE0MTQsMjYuMTAyNzIwMl0sCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICAuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKCiAgICAgICAgICAgIHZhciBjaXJjbGVfMzEwMDAyNDY4N2EzNDY3M2I2OGUzY2ZiMzA3OWVhMjYgPSBMLmNpcmNsZSgKICAgICAgICAgICAgICAgIFs0NC40MzYxNDE0LDI2LjEwMjcyMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAid2hpdGUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IGZhbHNlLAogICJmaWxsQ29sb3IiOiAid2hpdGUiLAogICJmaWxsT3BhY2l0eSI6IDAuMiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDIwMDAsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNGU0OTRkMTM5Nzg2NDAxZGI0MDU2NGVmMmU2OTI5YTYpOwogICAgICAgICAgICAKICAgIAoKICAgICAgICAgICAgdmFyIGNpcmNsZV85YTgzOWQ0NjUxNGE0ZDJhYjJkZmQyNDdlYWE4MjNiYiA9IEwuY2lyY2xlKAogICAgICAgICAgICAgICAgWzQ0LjQzNjE0MTQsMjYuMTAyNzIwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJ3aGl0ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogZmFsc2UsCiAgImZpbGxDb2xvciI6ICJ3aGl0ZSIsCiAgImZpbGxPcGFjaXR5IjogMC4yLAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNDAwMCwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF80ZTQ5NGQxMzk3ODY0MDFkYjQwNTY0ZWYyZTY5MjlhNik7CiAgICAgICAgICAgIAogICAgCgogICAgICAgICAgICB2YXIgY2lyY2xlXzI2ZWYyMjU3ZGE2NzQ2MTFiNGZjNmU1NTI3YzI0NWQyID0gTC5jaXJjbGUoCiAgICAgICAgICAgICAgICBbNDQuNDM2MTQxNCwyNi4xMDI3MjAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIndoaXRlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiBmYWxzZSwKICAiZmlsbENvbG9yIjogIndoaXRlIiwKICAiZmlsbE9wYWNpdHkiOiAwLjIsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA2MDAwLAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCiAgICAKCiAgICAgICAgICAgIHZhciBjaXJjbGVfMGYwY2Y0MzlkZjk5NDU1Y2JiNzVmOGEwMTdhYWMyMWEgPSBMLmNpcmNsZSgKICAgICAgICAgICAgICAgIFs0NC40MzYxNDE0LDI2LjEwMjcyMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmxhY2siLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IGZhbHNlLAogICJmaWxsQ29sb3IiOiAiYmxhY2siLAogICJmaWxsT3BhY2l0eSI6IDAuMiwKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDEwMDAwLAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzRlNDk0ZDEzOTc4NjQwMWRiNDA1NjRlZjJlNjkyOWE2KTsKICAgICAgICAgICAgCjwvc2NyaXB0Pg== onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7fc585268080>"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# create map\n",
"map_clusters = folium.Map(location=[latitude, longitude], zoom_start=11)\n",
"\n",
"# set color scheme for the clusters\n",
"x = np.arange(kclusters)\n",
"ys = [i+x+(i*x)**2 for i in range(kclusters)]\n",
"colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))\n",
"rainbow = [colors.rgb2hex(i) for i in colors_array]\n",
"\n",
"# add markers to the map\n",
"for lat, lon, poi, cluster, sector,SectorPopulation in zip(venues_cluster['Latitude'], venues_cluster['Longitude'], venues_cluster['Neighborhood'], venues_cluster['NeighborhoodCluster'], venues_cluster['Sector'],venues_cluster['SectorPopulation']):\n",
" label = folium.Popup(str(poi) + ' - Cluster ' + str(cluster)+ ' ' + str(sector) + ' ' + str(SectorPopulation), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius=5,\n",
" popup=label,\n",
" color=rainbow[cluster-1],\n",
" fill=True,\n",
" fill_color=rainbow[cluster-1],\n",
" fill_opacity=0.7).add_to(map_clusters)\n",
"folium.Marker(bucharest_center).add_to(map_clusters)\n",
"folium.Circle(bucharest_center, radius=2000, fill=False, color='white').add_to(map_clusters)\n",
"folium.Circle(bucharest_center, radius=4000, fill=False, color='white').add_to(map_clusters)\n",
"folium.Circle(bucharest_center, radius=6000, fill=False, color='white').add_to(map_clusters)\n",
"folium.Circle(bucharest_center, radius=10000, fill=False, color='black').add_to(map_clusters) \n",
"map_clusters"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th></th>\n",
" <th>Neighborhood Count</th>\n",
" </tr>\n",
" <tr>\n",
" <th>NeighborhoodCluster</th>\n",
" <th>2nd Most Common Restaurant</th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th rowspan=\"3\" valign=\"top\">0</th>\n",
" <th>Bakery</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Coffee Shop</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Lounge</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"3\" valign=\"top\">1</th>\n",
" <th>Coffee Shop</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Lounge</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"14\" valign=\"top\">2</th>\n",
" <th>Bar</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Bus Station</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Café</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Coffee Shop</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Dessert Shop</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Fast Food Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Gym / Fitness Center</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Middle Eastern Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pizza Place</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pub</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Romanian Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Sandwich Place</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Soccer Field</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Supermarket</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <th>Hotel</th>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"7\" valign=\"top\">4</th>\n",
" <th>Burger Joint</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Café</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Clothing Store</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Italian Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pizza Place</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Romanian Restaurant</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Supermarket</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th rowspan=\"3\" valign=\"top\">5</th>\n",
" <th>Bus Station</th>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hotel</th>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Plaza</th>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Count\n",
"NeighborhoodCluster 2nd Most Common Restaurant \n",
"0 Bakery 1\n",
" Coffee Shop 1\n",
" Lounge 2\n",
"1 Coffee Shop 2\n",
" Lounge 1\n",
" Restaurant 1\n",
"2 Bar 1\n",
" Bus Station 1\n",
" Café 2\n",
" Coffee Shop 1\n",
" Dessert Shop 1\n",
" Fast Food Restaurant 1\n",
" Gym / Fitness Center 1\n",
" Middle Eastern Restaurant 1\n",
" Pizza Place 1\n",
" Pub 1\n",
" Romanian Restaurant 1\n",
" Sandwich Place 1\n",
" Soccer Field 2\n",
" Supermarket 1\n",
"3 Hotel 4\n",
"4 Burger Joint 1\n",
" Café 1\n",
" Clothing Store 1\n",
" Italian Restaurant 1\n",
" Pizza Place 1\n",
" Romanian Restaurant 1\n",
" Supermarket 2\n",
"5 Bus Station 2\n",
" Hotel 1\n",
" Plaza 1"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#print(venues_cluster.groupby(['NeighborhoodCluster','1st Most Common Restaurant' ]).count()[['Neighborhood']].rename(columns={\"Neighborhood\": \"Neighborhood Count\"}))\n",
"\n",
"venues_cluster.groupby(['NeighborhoodCluster','2nd Most Common Restaurant' ]).count()[['Neighborhood']].rename(columns={\"Neighborhood\": \"Neighborhood Count\"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Methodology\n",
"\n",
"I have used various data from wikipedia to analyze the places around Bucharest and counted number of safe places and drinking places.\n",
"analysis is the data was done by seeing the ratings and all.\n",
"Then I used Maps and got errors. \n",
"On the map the points depict the places or neighbourhoods segregated or clustered."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Result"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The cyan coloured places are dry and safe for the teenagers less than 18 years old.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conclusion"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The places center to Bucharest are less alcoholic places. Parents can send their kids to these places.\n",
"these are safe and dry places"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#SofiaSunam"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python",
"language": "python",
"name": "conda-env-python-py"
},
"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.6.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment