Skip to content

Instantly share code, notes, and snippets.

@bertrandobi
Created February 3, 2019 22:44
Show Gist options
  • Save bertrandobi/8a8f3039cbe26caff970e4cb758c9d2a to your computer and use it in GitHub Desktop.
Save bertrandobi/8a8f3039cbe26caff970e4cb758c9d2a to your computer and use it in GitHub Desktop.
Created on Cognitive Class Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Segmenting and Clustering Neighborhoods in Toronto"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Project Objectives:\n",
"- Scrap Toronto Neighbourhood Data from Wikipedia\n",
"- wrangle the data, clean it, and then read it into a pandas dataframe so that it is in a structured format like the New York dataset\n",
"- explore and cluster the neighborhoods in the city of Toronto"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Import liabraries needed for the project"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Libraries imported.\n"
]
}
],
"source": [
"# -*- coding: utf-8 -*-\n",
"import os,sys\n",
"import urllib\n",
"import requests \n",
"from urllib.request import urlopen\n",
"from bs4 import BeautifulSoup\n",
"import numpy as np # library to handle data in a vectorized manner\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",
"import json # library to handle JSON files\n",
"#!conda install -c conda-forge geopy --yes # uncomment this line if you haven't completed the Foursquare API lab\n",
"from geopy.geocoders import Nominatim # convert an address into latitude and longitude values\n",
"import requests # library to handle requests\n",
"from pandas.io.json import json_normalize # tranform JSON file into a pandas dataframe\n",
"# Matplotlib and associated plotting modules\n",
"import matplotlib.cm as cm\n",
"import matplotlib.colors as colors\n",
"# import k-means from clustering stage\n",
"from sklearn.cluster import KMeans\n",
"#!conda install -c conda-forge folium=0.5.0 --yes # uncomment this line if you haven't completed the Foursquare API lab\n",
"import folium # map rendering library\n",
"print('Libraries imported.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Scrap Toronto Neighbourhood data from Wikipaedia using postal codes "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"URL = \"https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M\"\n",
"page = urlopen(URL)\n",
"soup = BeautifulSoup(page)\n",
"page.close()\n",
" \n",
"fp = open(\"data.csv\",\"w\")\n",
"tables = soup.findAll('table')\n",
"tab = tables[0]\n",
"for tr in tab.tbody.findAll('tr'):\n",
" #print(tr.findAll('th'))\n",
" for th in tr.findAll('th'):\n",
" text = th.getText().strip()+','\n",
" fp.write(text)\n",
" for td in tr.findAll('td'):\n",
" text = td.getText().strip()+','\n",
" fp.write(text)\n",
" fp.write('\\n')\n",
"fp.close()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Represent data in a Dataframe"
]
},
{
"cell_type": "code",
"execution_count": 3,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1A</td>\n",
" <td>Not assigned</td>\n",
" <td>Not assigned</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M2A</td>\n",
" <td>Not assigned</td>\n",
" <td>Not assigned</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M3A</td>\n",
" <td>North York</td>\n",
" <td>Parkwoods</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M4A</td>\n",
" <td>North York</td>\n",
" <td>Victoria Village</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M5A</td>\n",
" <td>Downtown Toronto</td>\n",
" <td>Harbourfront</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood\n",
"0 M1A Not assigned Not assigned\n",
"1 M2A Not assigned Not assigned\n",
"2 M3A North York Parkwoods\n",
"3 M4A North York Victoria Village\n",
"4 M5A Downtown Toronto Harbourfront"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs = pd.read_csv('data.csv')\n",
"dfs.drop('Unnamed: 3',axis=1,inplace = True)\n",
"dfs.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(289, 3)"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs.shape"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(212, 3)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs1 = dfs[ ~ dfs['Borough'].str.contains('Not assigned')]\n",
"dfs1.shape"
]
},
{
"cell_type": "code",
"execution_count": 6,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>RougeMalvern</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood\n",
"0 M1B Scarborough RougeMalvern\n",
"1 M1C Scarborough Highland CreekRouge HillPort Union\n",
"2 M1E Scarborough GuildwoodMorningsideWest Hill\n",
"3 M1G Scarborough Woburn\n",
"4 M1H Scarborough Cedarbrae"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grouped = dfs1.groupby(['Postcode','Borough'],as_index=False)\n",
"dfs2 = pd.DataFrame(grouped.sum())\n",
"dfs2.head()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(103, 3)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs2.shape"
]
},
{
"cell_type": "code",
"execution_count": 9,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>RougeMalvern</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood\n",
"0 M1B Scarborough RougeMalvern\n",
"1 M1C Scarborough Highland CreekRouge HillPort Union\n",
"2 M1E Scarborough GuildwoodMorningsideWest Hill\n",
"3 M1G Scarborough Woburn\n",
"4 M1H Scarborough Cedarbrae"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"for i in range(len(dfs2)):\n",
" #if dfs2.iloc[i,2] = \"Not assigned\"\n",
" line_data=dfs2.iloc[i,:]\n",
" if line_data['Neighbourhood'] == 'Not assigned':\n",
" line_data['Neighbourhood'] = line_data['Borough']\n",
"dfs2.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Use Geospatial_Coordinates.csv to trace dataframe downloaded and save in the path"
]
},
{
"cell_type": "code",
"execution_count": 10,
"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>Postcode</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Latitude Longitude\n",
"0 M1B 43.806686 -79.194353\n",
"1 M1C 43.784535 -79.160497\n",
"2 M1E 43.763573 -79.188711\n",
"3 M1G 43.770992 -79.216917\n",
"4 M1H 43.773136 -79.239476"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"geo_data = pd.read_csv(\"Geospatial_Coordinates.csv\")\n",
"geo_data.rename(columns={'Postal Code':'Postcode'}, inplace = True)\n",
"geo_data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Merge dfs2 and geo_data by column \"Postcode\""
]
},
{
"cell_type": "code",
"execution_count": 12,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood Latitude \\\n",
"0 M1B Scarborough RougeMalvern 43.806686 \n",
"1 M1C Scarborough Highland CreekRouge HillPort Union 43.784535 \n",
"2 M1E Scarborough GuildwoodMorningsideWest Hill 43.763573 \n",
"3 M1G Scarborough Woburn 43.770992 \n",
"4 M1H Scarborough Cedarbrae 43.773136 \n",
"\n",
" Longitude \n",
"0 -79.194353 \n",
"1 -79.160497 \n",
"2 -79.188711 \n",
"3 -79.216917 \n",
"4 -79.239476 "
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs3 = pd.merge(dfs2, geo_data, on='Postcode')\n",
"dfs3.head()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The dataframe has 11 boroughs and 103 neighborhoods.\n"
]
}
],
"source": [
"print('The dataframe has {} boroughs and {} neighborhoods.'.format(len(dfs3['Borough'].unique()),dfs3.shape[0]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Find the latitude and longitude of Toronto of Canada"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The geograpical coordinate of Toronto are 43.653963, -79.387207.\n"
]
}
],
"source": [
"address = 'Toronto, CA'\n",
"geolocator = Nominatim()\n",
"location = geolocator.geocode(address)\n",
"latitude = location.latitude\n",
"longitude = location.longitude\n",
"print('The geograpical coordinate of Toronto are {}, {}.'.format(latitude, longitude))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create map of Toronto using latitude and longitude values"
]
},
{
"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%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDMuNjUzOTYzLC03OS4zODcyMDddLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyX2NkNWI2NDE4ZTJjZDQzMzU5MGMyY2JhY2ZmNTE2NWI2ID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMTgzZWRlZjQ1OGU0MmMzYmVjYjFjNGY2NmIwMGI1NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwNjY4NjI5OTk5OTk5NiwtNzkuMTk0MzUzNDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmM4YzQ0MzliZjQzNDhkN2I4Y2JjMDI4M2VhNzliODEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjIyZjY0MWQ5ZmVmNDI4M2E5N2I4NDM2Y2RjZDkzZjUgPSAkKCc8ZGl2IGlkPSJodG1sXzIyMmY2NDFkOWZlZjQyODNhOTdiODQzNmNkY2Q5M2Y1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZU1hbHZlcm4sIFNjYXJib3JvdWdoPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mYzhjNDQzOWJmNDM0OGQ3YjhjYmMwMjgzZWE3OWI4MS5zZXRDb250ZW50KGh0bWxfMjIyZjY0MWQ5ZmVmNDI4M2E5N2I4NDM2Y2RjZDkzZjUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzE4M2VkZWY0NThlNDJjM2JlY2IxYzRmNjZiMDBiNTcuYmluZFBvcHVwKHBvcHVwX2ZjOGM0NDM5YmY0MzQ4ZDdiOGNiYzAyODNlYTc5YjgxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzg5YWQ5NmU2ZjljYTQ4ZTVhNmI4YzRiZjRmYTM0MjllID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg0NTM1MSwtNzkuMTYwNDk3MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmU0YTM4NGZhYmU5NGM4YmEwOGJhZjcyNjZmMTkyNzggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2RiYzhhMzcxMjI4NGQ5NTg2ZjMyN2I2NGIzZGI1MGMgPSAkKCc8ZGl2IGlkPSJodG1sXzNkYmM4YTM3MTIyODRkOTU4NmYzMjdiNjRiM2RiNTBjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdobGFuZCBDcmVla1JvdWdlIEhpbGxQb3J0IFVuaW9uLCBTY2FyYm9yb3VnaDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmU0YTM4NGZhYmU5NGM4YmEwOGJhZjcyNjZmMTkyNzguc2V0Q29udGVudChodG1sXzNkYmM4YTM3MTIyODRkOTU4NmYzMjdiNjRiM2RiNTBjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzg5YWQ5NmU2ZjljYTQ4ZTVhNmI4YzRiZjRmYTM0MjllLmJpbmRQb3B1cChwb3B1cF8yZTRhMzg0ZmFiZTk0YzhiYTA4YmFmNzI2NmYxOTI3OCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hYjA2MmZkMTc5MGY0OTEzOWYyNDBjMmYyYzk4NmY2MCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MzU3MjYsLTc5LjE4ODcxMTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjI4OTY5YTFlMjM3NGQwNTg5NGY1ZDM1M2Y0NGEwZWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmI0OWRhNjljZjMxNGU2MWJmOGUxZWI3ZmEwMTM4MDMgPSAkKCc8ZGl2IGlkPSJodG1sX2ZiNDlkYTY5Y2YzMTRlNjFiZjhlMWViN2ZhMDEzODAzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HdWlsZHdvb2RNb3JuaW5nc2lkZVdlc3QgSGlsbCwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2IyODk2OWExZTIzNzRkMDU4OTRmNWQzNTNmNDRhMGVjLnNldENvbnRlbnQoaHRtbF9mYjQ5ZGE2OWNmMzE0ZTYxYmY4ZTFlYjdmYTAxMzgwMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hYjA2MmZkMTc5MGY0OTEzOWYyNDBjMmYyYzk4NmY2MC5iaW5kUG9wdXAocG9wdXBfYjI4OTY5YTFlMjM3NGQwNTg5NGY1ZDM1M2Y0NGEwZWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmNlYWZhZjJkN2Q4NGJmNDkyYWJlMDhmYmM2ODQwOTggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzA5OTIxLC03OS4yMTY5MTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYmYxMzhlODY5MTc0OWQzYmQxZWI1MjhiMzYyYmNiYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82MzljMzRhNTEzYTA0ZDI5YjQzNTg5ZGY2NWM3MjcxNiA9ICQoJzxkaXYgaWQ9Imh0bWxfNjM5YzM0YTUxM2EwNGQyOWI0MzU4OWRmNjVjNzI3MTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldvYnVybiwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RiZjEzOGU4NjkxNzQ5ZDNiZDFlYjUyOGIzNjJiY2JjLnNldENvbnRlbnQoaHRtbF82MzljMzRhNTEzYTA0ZDI5YjQzNTg5ZGY2NWM3MjcxNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iY2VhZmFmMmQ3ZDg0YmY0OTJhYmUwOGZiYzY4NDA5OC5iaW5kUG9wdXAocG9wdXBfZGJmMTM4ZTg2OTE3NDlkM2JkMWViNTI4YjM2MmJjYmMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZjljM2YxNzUxNDA0NGRhMjgzOTdiM2QxOTc2NTUwYjIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzMxMzYsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VhZTVmM2FiODBmYzQzM2E5YTQzYjg5NDRiYmY0NjdlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2RkMDYzNjJlODU4YTQwOGE4ZGI3ZDFkNDNiYzVjMGMyID0gJCgnPGRpdiBpZD0iaHRtbF9kZDA2MzYyZTg1OGE0MDhhOGRiN2QxZDQzYmM1YzBjMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VkYXJicmFlLCBTY2FyYm9yb3VnaDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZWFlNWYzYWI4MGZjNDMzYTlhNDNiODk0NGJiZjQ2N2Uuc2V0Q29udGVudChodG1sX2RkMDYzNjJlODU4YTQwOGE4ZGI3ZDFkNDNiYzVjMGMyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Y5YzNmMTc1MTQwNDRkYTI4Mzk3YjNkMTk3NjU1MGIyLmJpbmRQb3B1cChwb3B1cF9lYWU1ZjNhYjgwZmM0MzNhOWE0M2I4OTQ0YmJmNDY3ZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jNjgxNWU3YmI2MWE0ZTQ3YTE5Mjk0YTk0MDhhZDA5NSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NDczNDIsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzAzNWViNDhmMTQ3MDRmOWE5Y2M3Nzc3MmU0MWIyOWQ3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzExOTc0ZTM4NGIyODQ4NmU5MzRmN2ExNWVmMzQwMmNiID0gJCgnPGRpdiBpZD0iaHRtbF8xMTk3NGUzODRiMjg0ODZlOTM0ZjdhMTVlZjM0MDJjYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U2NhcmJvcm91Z2ggVmlsbGFnZSwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzAzNWViNDhmMTQ3MDRmOWE5Y2M3Nzc3MmU0MWIyOWQ3LnNldENvbnRlbnQoaHRtbF8xMTk3NGUzODRiMjg0ODZlOTM0ZjdhMTVlZjM0MDJjYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jNjgxNWU3YmI2MWE0ZTQ3YTE5Mjk0YTk0MDhhZDA5NS5iaW5kUG9wdXAocG9wdXBfMDM1ZWI0OGYxNDcwNGY5YTljYzc3NzcyZTQxYjI5ZDcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGM5ODk4MWI3NDMxNGEyM2JkNmM1ZDI2NTBlODZlNGEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hYzBiMjUwMTE1ZTI0NzU3YTk0NzJlY2RlNWEzYWY2MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMWIyNzA0MTdmNmI0ZDhiYjVhNjNjNDAzYmVhM2ZhOSA9ICQoJzxkaXYgaWQ9Imh0bWxfZDFiMjcwNDE3ZjZiNGQ4YmI1YTYzYzQwM2JlYTNmYTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgQmlyY2htb3VudCBQYXJrSW9udmlld0tlbm5lZHkgUGFyaywgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FjMGIyNTAxMTVlMjQ3NTdhOTQ3MmVjZGU1YTNhZjYyLnNldENvbnRlbnQoaHRtbF9kMWIyNzA0MTdmNmI0ZDhiYjVhNjNjNDAzYmVhM2ZhOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84Yzk4OTgxYjc0MzE0YTIzYmQ2YzVkMjY1MGU4NmU0YS5iaW5kUG9wdXAocG9wdXBfYWMwYjI1MDExNWUyNDc1N2E5NDcyZWNkZTVhM2FmNjIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfN2JjYTQ4MDFlYzkzNDEzMGFiNWVlMDM1NWNlNjM2Y2IgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTExMTE3MDAwMDAwMDQsLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWNmM2RkMDkxNzg3NDc1OGE1NTExODZlYTVjMzBkNTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDczMmRjZTI2NzI2NDM2MmE1MGY3ZTkwZjk2MzAyNWEgPSAkKCc8ZGl2IGlkPSJodG1sX2Q3MzJkY2UyNjcyNjQzNjJhNTBmN2U5MGY5NjMwMjVhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGFpcmxlYUdvbGRlbiBNaWxlT2FrcmlkZ2UsIFNjYXJib3JvdWdoPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lY2YzZGQwOTE3ODc0NzU4YTU1MTE4NmVhNWMzMGQ1Mi5zZXRDb250ZW50KGh0bWxfZDczMmRjZTI2NzI2NDM2MmE1MGY3ZTkwZjk2MzAyNWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfN2JjYTQ4MDFlYzkzNDEzMGFiNWVlMDM1NWNlNjM2Y2IuYmluZFBvcHVwKHBvcHVwX2VjZjNkZDA5MTc4NzQ3NThhNTUxMTg2ZWE1YzMwZDUyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzc5ODZmNWM0YzY0ODQ5N2U4YzI3YWQwMTk5YjNkNGMwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE2MzE2LC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNzUzMTE0ZTNhMGE0ODdmOTA4MGI1NTFiZWE5YzYzNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85MzJkNTJmMjk0NTk0YjU4YWJmOTMzYzNkZTM1ZjA2YiA9ICQoJzxkaXYgaWQ9Imh0bWxfOTMyZDUyZjI5NDU5NGI1OGFiZjkzM2MzZGUzNWYwNmIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsaWZmY3Jlc3RDbGlmZnNpZGVTY2FyYm9yb3VnaCBWaWxsYWdlIFdlc3QsIFNjYXJib3JvdWdoPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNzUzMTE0ZTNhMGE0ODdmOTA4MGI1NTFiZWE5YzYzNy5zZXRDb250ZW50KGh0bWxfOTMyZDUyZjI5NDU5NGI1OGFiZjkzM2MzZGUzNWYwNmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzk4NmY1YzRjNjQ4NDk3ZThjMjdhZDAxOTliM2Q0YzAuYmluZFBvcHVwKHBvcHVwX2I3NTMxMTRlM2EwYTQ4N2Y5MDgwYjU1MWJlYTljNjM3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzJmMjY1M2NiYjZkOTQ1MWFhYTI4OTk3NmY2YTQzNDM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkyNjU3MDAwMDAwMDA0LC03OS4yNjQ4NDgxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzVhYjNhNTA4Nzc4NDRiZDlhNTVjMTZjNzA3NjRhZjk3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2EyNzgxMzBmYmY4NTQ3ZjU4MzQ2YzM4MjUxYjRiMTNmID0gJCgnPGRpdiBpZD0iaHRtbF9hMjc4MTMwZmJmODU0N2Y1ODM0NmMzODI1MWI0YjEzZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmlyY2ggQ2xpZmZDbGlmZnNpZGUgV2VzdCwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzVhYjNhNTA4Nzc4NDRiZDlhNTVjMTZjNzA3NjRhZjk3LnNldENvbnRlbnQoaHRtbF9hMjc4MTMwZmJmODU0N2Y1ODM0NmMzODI1MWI0YjEzZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yZjI2NTNjYmI2ZDk0NTFhYWEyODk5NzZmNmE0MzQzNC5iaW5kUG9wdXAocG9wdXBfNWFiM2E1MDg3Nzg0NGJkOWE1NWMxNmM3MDc2NGFmOTcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzZlNTU0MWVmNWFlNGUxYjk3NDQ2MjI2YTY4ZWE0YzAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTc0MDk2LC03OS4yNzMzMDQwMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85NTU3Y2RlY2QwZDI0ZWFmOTU3NjAzMjk2NGFlOGE4NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mZTM2MTA4OGUwYzk0NmY0OGYwMzU0ZmQwYWI2OTMxOSA9ICQoJzxkaXYgaWQ9Imh0bWxfZmUzNjEwODhlMGM5NDZmNDhmMDM1NGZkMGFiNjkzMTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrU2NhcmJvcm91Z2ggVG93biBDZW50cmVXZXhmb3JkIEhlaWdodHMsIFNjYXJib3JvdWdoPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85NTU3Y2RlY2QwZDI0ZWFmOTU3NjAzMjk2NGFlOGE4Ny5zZXRDb250ZW50KGh0bWxfZmUzNjEwODhlMGM5NDZmNDhmMDM1NGZkMGFiNjkzMTkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzZlNTU0MWVmNWFlNGUxYjk3NDQ2MjI2YTY4ZWE0YzAuYmluZFBvcHVwKHBvcHVwXzk1NTdjZGVjZDBkMjRlYWY5NTc2MDMyOTY0YWU4YTg3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQxOTA5OTNmOGJhZTQ3YzliODA5OGMyNzlmZjEwYzY2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzUwMDcxNTAwMDAwMDA0LC03OS4yOTU4NDkxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjMTQzZjVkMDdhZjRkNzZhM2Q5NjM4MDEwNDA2NjQyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZhYjg4MWQ5ZmQ1NzQyNDA4Nzk1ZjQxOGIxYzZjMzFjID0gJCgnPGRpdiBpZD0iaHRtbF9mYWI4ODFkOWZkNTc0MjQwODc5NWY0MThiMWM2YzMxYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TWFyeXZhbGVXZXhmb3JkLCBTY2FyYm9yb3VnaDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmMxNDNmNWQwN2FmNGQ3NmEzZDk2MzgwMTA0MDY2NDIuc2V0Q29udGVudChodG1sX2ZhYjg4MWQ5ZmQ1NzQyNDA4Nzk1ZjQxOGIxYzZjMzFjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQxOTA5OTNmOGJhZTQ3YzliODA5OGMyNzlmZjEwYzY2LmJpbmRQb3B1cChwb3B1cF9mYzE0M2Y1ZDA3YWY0ZDc2YTNkOTYzODAxMDQwNjY0Mik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hYTVkNWQ4YmVmOWE0MDVjYjkyNWFhNDRiM2M1ZGE3NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5NDIwMDMsLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzAyYzg2ZmExZWVhZTQ5YzdiZDhjZjE2MjkxZjcxM2Q2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZmNjJhZTEwZTUyMjQ5MWQ5ZTE5M2VmNTM4OGJmMDhhID0gJCgnPGRpdiBpZD0iaHRtbF82ZjYyYWUxMGU1MjI0OTFkOWUxOTNlZjUzODhiZjA4YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0LCBTY2FyYm9yb3VnaDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDJjODZmYTFlZWFlNDljN2JkOGNmMTYyOTFmNzEzZDYuc2V0Q29udGVudChodG1sXzZmNjJhZTEwZTUyMjQ5MWQ5ZTE5M2VmNTM4OGJmMDhhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2FhNWQ1ZDhiZWY5YTQwNWNiOTI1YWE0NGIzYzVkYTc3LmJpbmRQb3B1cChwb3B1cF8wMmM4NmZhMWVlYWU0OWM3YmQ4Y2YxNjI5MWY3MTNkNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yZWI1ZDBiMWVlNTM0ZGYzOTE0Mzg3NDliMjEwNDYxNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MTYzNzUsLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjg3NzgyMzU2MmYxNDIwNmE1OGEwZTJmMWIwZjNjNmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGUyYTNmNjY2ZDk1NDM2MGIwMzkyYzIyZmFjY2QzNWYgPSAkKCc8ZGl2IGlkPSJodG1sX2RlMmEzZjY2NmQ5NTQzNjBiMDM5MmMyMmZhY2NkMzVmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGFya3MgQ29ybmVyc1N1bGxpdmFuVGFtIE8mIzM5O1NoYW50ZXIsIFNjYXJib3JvdWdoPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yODc3ODIzNTYyZjE0MjA2YTU4YTBlMmYxYjBmM2M2Zi5zZXRDb250ZW50KGh0bWxfZGUyYTNmNjY2ZDk1NDM2MGIwMzkyYzIyZmFjY2QzNWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMmViNWQwYjFlZTUzNGRmMzkxNDM4NzQ5YjIxMDQ2MTQuYmluZFBvcHVwKHBvcHVwXzI4Nzc4MjM1NjJmMTQyMDZhNThhMGUyZjFiMGYzYzZmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4NjdhODgxNzFkMzQyNGFiZDRiZjRmMGJhZTAzNjJiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODE1MjUyMiwtNzkuMjg0NTc3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lNGM5NWEyZjQ5MTc0MzhhYjk3MjQ5ZGRiMThmNGFlOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNzVkMTA2ODFlNjA0MWM2ODdiMGQ3MmRlNzE1ZDg2NCA9ICQoJzxkaXYgaWQ9Imh0bWxfYzc1ZDEwNjgxZTYwNDFjNjg3YjBkNzJkZTcxNWQ4NjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFnaW5jb3VydCBOb3J0aEwmIzM5O0Ftb3JlYXV4IEVhc3RNaWxsaWtlblN0ZWVsZXMgRWFzdCwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U0Yzk1YTJmNDkxNzQzOGFiOTcyNDlkZGIxOGY0YWU5LnNldENvbnRlbnQoaHRtbF9jNzVkMTA2ODFlNjA0MWM2ODdiMGQ3MmRlNzE1ZDg2NCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mODY3YTg4MTcxZDM0MjRhYmQ0YmY0ZjBiYWUwMzYyYi5iaW5kUG9wdXAocG9wdXBfZTRjOTVhMmY0OTE3NDM4YWI5NzI0OWRkYjE4ZjRhZTkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmRlNDRkNWI0YmU0NDgwNThmMTMyYzJiMzFhM2E4NzUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTk1MjUyMDAwMDAwMDUsLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTNmNjA0ZWE1M2UxNDIyZDliYmQwMzRmM2IxYmZiZTUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2E2MWEwNGQ0MTg0NGIyYjlhNzhhYmM2M2ZhMjhjMzQgPSAkKCc8ZGl2IGlkPSJodG1sXzNhNjFhMDRkNDE4NDRiMmI5YTc4YWJjNjNmYTI4YzM0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MJiMzOTtBbW9yZWF1eCBXZXN0U3RlZWxlcyBXZXN0LCBTY2FyYm9yb3VnaDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTNmNjA0ZWE1M2UxNDIyZDliYmQwMzRmM2IxYmZiZTUuc2V0Q29udGVudChodG1sXzNhNjFhMDRkNDE4NDRiMmI5YTc4YWJjNjNmYTI4YzM0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2JkZTQ0ZDViNGJlNDQ4MDU4ZjEzMmMyYjMxYTNhODc1LmJpbmRQb3B1cChwb3B1cF9hM2Y2MDRlYTUzZTE0MjJkOWJiZDAzNGYzYjFiZmJlNSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hOWVmNzhhOGE5NmQ0ZThhODU5N2VhYThjZWVlMTczMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgzNjEyNDcwMDAwMDAwNiwtNzkuMjA1NjM2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZThiYWQ5NGNmODVmNDEwMThjNDgyMDg0MDk3NDMxYmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjUxMWUyZDZmYjEzNDMxZmJjNzBkMWFlZDIwYjE3N2IgPSAkKCc8ZGl2IGlkPSJodG1sXzI1MTFlMmQ2ZmIxMzQzMWZiYzcwZDFhZWQyMGIxNzdiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5VcHBlciBSb3VnZSwgU2NhcmJvcm91Z2g8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U4YmFkOTRjZjg1ZjQxMDE4YzQ4MjA4NDA5NzQzMWJmLnNldENvbnRlbnQoaHRtbF8yNTExZTJkNmZiMTM0MzFmYmM3MGQxYWVkMjBiMTc3Yik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hOWVmNzhhOGE5NmQ0ZThhODU5N2VhYThjZWVlMTczMC5iaW5kUG9wdXAocG9wdXBfZThiYWQ5NGNmODVmNDEwMThjNDgyMDg0MDk3NDMxYmYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTQzY2FkOTFjNTNjNGFjNzlkMDExM2YzNmM1MTIyNDEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My44MDM3NjIyLC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA0NzU1NTcyNDI2ZDQ2ZmM5YTJkZjZjNTU2MzAwOTVjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc2ZWY3Njc1YTY1MTQ0NzA5MmVkODdiY2VmOWJjODdhID0gJCgnPGRpdiBpZD0iaHRtbF83NmVmNzY3NWE2NTE0NDcwOTJlZDg3YmNlZjliYzg3YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGlsbGNyZXN0IFZpbGxhZ2UsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzA0NzU1NTcyNDI2ZDQ2ZmM5YTJkZjZjNTU2MzAwOTVjLnNldENvbnRlbnQoaHRtbF83NmVmNzY3NWE2NTE0NDcwOTJlZDg3YmNlZjliYzg3YSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hNDNjYWQ5MWM1M2M0YWM3OWQwMTEzZjM2YzUxMjI0MS5iaW5kUG9wdXAocG9wdXBfMDQ3NTU1NzI0MjZkNDZmYzlhMmRmNmM1NTYzMDA5NWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNmRiOWQxMzA0NTk0NGQ0MGJjMjE0NGRmMGIzMDlmMWEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Nzg1MTc1LC03OS4zNDY1NTU3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2NjYjg3MTg3MzQwMzQ1M2Y5YWZkY2UxYzlhNmRhNmExID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Y0MmQ1OGE0N2UwZDRiN2U4MzlmZjI0N2RhNmU2NGZiID0gJCgnPGRpdiBpZD0iaHRtbF9mNDJkNThhNDdlMGQ0YjdlODM5ZmYyNDdkYTZlNjRmYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmFpcnZpZXdIZW5yeSBGYXJtT3Jpb2xlLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jY2I4NzE4NzM0MDM0NTNmOWFmZGNlMWM5YTZkYTZhMS5zZXRDb250ZW50KGh0bWxfZjQyZDU4YTQ3ZTBkNGI3ZTgzOWZmMjQ3ZGE2ZTY0ZmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNmRiOWQxMzA0NTk0NGQ0MGJjMjE0NGRmMGIzMDlmMWEuYmluZFBvcHVwKHBvcHVwX2NjYjg3MTg3MzQwMzQ1M2Y5YWZkY2UxYzlhNmRhNmExKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y5YTNjZDIzNjgzYjQ3ZTdiNTk4Y2ZlYjIzM2MxOWM3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg2OTQ3MywtNzkuMzg1OTc1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzVmZDUzODhhNjU2NzQ0NGE4ZTg4YjdkYzZhYjc3ODI5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg4NmY5Y2EwMTFjYTQ4OTZiNTIyYzU4M2I5MDIyZmQzID0gJCgnPGRpdiBpZD0iaHRtbF84ODZmOWNhMDExY2E0ODk2YjUyMmM1ODNiOTAyMmZkMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmF5dmlldyBWaWxsYWdlLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81ZmQ1Mzg4YTY1Njc0NDRhOGU4OGI3ZGM2YWI3NzgyOS5zZXRDb250ZW50KGh0bWxfODg2ZjljYTAxMWNhNDg5NmI1MjJjNTgzYjkwMjJmZDMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZjlhM2NkMjM2ODNiNDdlN2I1OThjZmViMjMzYzE5YzcuYmluZFBvcHVwKHBvcHVwXzVmZDUzODhhNjU2NzQ0NGE4ZTg4YjdkYzZhYjc3ODI5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFkOWJhM2MwMjEyZjRjYWRiZTVjMjdhYmUyNjUzYWY2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDkwMiwtNzkuMzc0NzE0MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTJkYjJkMWM1YTYwNGY4MmE0ZjRjNTYzNTU2ZDJmMmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDQxMTk1ZDQyMzczNDJiMjg3NmQzOWI2OWU2ZTYzY2MgPSAkKCc8ZGl2IGlkPSJodG1sXzQ0MTE5NWQ0MjM3MzQyYjI4NzZkMzliNjllNmU2M2NjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TaWx2ZXIgSGlsbHNZb3JrIE1pbGxzLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85MmRiMmQxYzVhNjA0ZjgyYTRmNGM1NjM1NTZkMmYyZS5zZXRDb250ZW50KGh0bWxfNDQxMTk1ZDQyMzczNDJiMjg3NmQzOWI2OWU2ZTYzY2MpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMWQ5YmEzYzAyMTJmNGNhZGJlNWMyN2FiZTI2NTNhZjYuYmluZFBvcHVwKHBvcHVwXzkyZGIyZDFjNWE2MDRmODJhNGY0YzU2MzU1NmQyZjJlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNiMzU5MzE2MWEwYzQ0ZjdiYjMwYjg1MTVmMTc2Njk0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg5MDUzLC03OS40MDg0OTI3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iN2U4NzY5YzNkZDc0OGEwYThhNTc5Mzk1OTg0N2E3YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNDMyMWYxNGJlNWU0Y2YyODM4YzA3NWI3Y2ExMDM0MiA9ICQoJzxkaXYgaWQ9Imh0bWxfMTQzMjFmMTRiZTVlNGNmMjgzOGMwNzViN2NhMTAzNDIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5ld3RvbmJyb29rV2lsbG93ZGFsZSwgTm9ydGggWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjdlODc2OWMzZGQ3NDhhMGE4YTU3OTM5NTk4NDdhN2Muc2V0Q29udGVudChodG1sXzE0MzIxZjE0YmU1ZTRjZjI4MzhjMDc1YjdjYTEwMzQyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzNiMzU5MzE2MWEwYzQ0ZjdiYjMwYjg1MTVmMTc2Njk0LmJpbmRQb3B1cChwb3B1cF9iN2U4NzY5YzNkZDc0OGEwYThhNTc5Mzk1OTg0N2E3Yyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82ZDQyNGMyOTExYTI0NTVhOGM4OThhOTRkZWZmMjVmMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDExOTksLTc5LjQwODQ5Mjc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc3NDY3NDJhZDVkYTRhMzZiZjIxODgwMjAyZTdhNmRhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2I4ZTQ4ZDEzYzk1ZTQ1MWQ5MzAyZTlhNTUyMzhiMjMwID0gJCgnPGRpdiBpZD0iaHRtbF9iOGU0OGQxM2M5NWU0NTFkOTMwMmU5YTU1MjM4YjIzMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSBTb3V0aCwgTm9ydGggWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzc0Njc0MmFkNWRhNGEzNmJmMjE4ODAyMDJlN2E2ZGEuc2V0Q29udGVudChodG1sX2I4ZTQ4ZDEzYzk1ZTQ1MWQ5MzAyZTlhNTUyMzhiMjMwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzZkNDI0YzI5MTFhMjQ1NWE4Yzg5OGE5NGRlZmYyNWYwLmJpbmRQb3B1cChwb3B1cF83NzQ2NzQyYWQ1ZGE0YTM2YmYyMTg4MDIwMmU3YTZkYSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81Yzk0Zjc4NDNjYTE0MzIwOWUxMzIzNmQ3YzgyYmM2MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1Mjc1ODI5OTk5OTk5NiwtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yYzFkMWE1MjI5NGY0OTczODQ4ZjM0ZmY0ZDQ2N2YwOCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hNDk0ZDBhYTVmMTQ0YjA4YWJkYjA0ZTIwZmE0OWU4NiA9ICQoJzxkaXYgaWQ9Imh0bWxfYTQ5NGQwYWE1ZjE0NGIwOGFiZGIwNGUyMGZhNDllODYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPllvcmsgTWlsbHMgV2VzdCwgTm9ydGggWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmMxZDFhNTIyOTRmNDk3Mzg0OGYzNGZmNGQ0NjdmMDguc2V0Q29udGVudChodG1sX2E0OTRkMGFhNWYxNDRiMDhhYmRiMDRlMjBmYTQ5ZTg2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzVjOTRmNzg0M2NhMTQzMjA5ZTEzMjM2ZDdjODJiYzYyLmJpbmRQb3B1cChwb3B1cF8yYzFkMWE1MjI5NGY0OTczODQ4ZjM0ZmY0ZDQ2N2YwOCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lNTM3YjFiNjYyN2M0NDVhOGJhZDc2YmQ2YzEyM2MxNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MjczNjQsLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWVhZTdlYjVhNmEyNGFiZWE4Yzc4YTQwYTQwZDFjNmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmEwNTcwMGQwMzdkNGI4NDkxNmU2YjUzZmVjNDllZGEgPSAkKCc8ZGl2IGlkPSJodG1sXzJhMDU3MDBkMDM3ZDRiODQ5MTZlNmI1M2ZlYzQ5ZWRhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlIFdlc3QsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFlYWU3ZWI1YTZhMjRhYmVhOGM3OGE0MGE0MGQxYzZlLnNldENvbnRlbnQoaHRtbF8yYTA1NzAwZDAzN2Q0Yjg0OTE2ZTZiNTNmZWM0OWVkYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lNTM3YjFiNjYyN2M0NDVhOGJhZDc2YmQ2YzEyM2MxNy5iaW5kUG9wdXAocG9wdXBfMWVhZTdlYjVhNmEyNGFiZWE4Yzc4YTQwYTQwZDFjNmUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDgzNGU4MmQwMjExNGRmZDk4ZGM2ODI4MTUzNzg1Y2IgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LC03OS4zMjk2NTY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzM2YzBjZmI2MjJhZDRlZGNhNzliOGI1ODBiZTIxNDkyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzAyNGU3YmE4MmY0ZTQwOTRhODY5YjM3OGYxOGJmOTI4ID0gJCgnPGRpdiBpZD0iaHRtbF8wMjRlN2JhODJmNGU0MDk0YTg2OWIzNzhmMThiZjkyOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFya3dvb2RzLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zNmMwY2ZiNjIyYWQ0ZWRjYTc5YjhiNTgwYmUyMTQ5Mi5zZXRDb250ZW50KGh0bWxfMDI0ZTdiYTgyZjRlNDA5NGE4NjliMzc4ZjE4YmY5MjgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZDgzNGU4MmQwMjExNGRmZDk4ZGM2ODI4MTUzNzg1Y2IuYmluZFBvcHVwKHBvcHVwXzM2YzBjZmI2MjJhZDRlZGNhNzliOGI1ODBiZTIxNDkyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFiZDZhMDkyNGFhZTQ2NDlhNDAzNzFhZmU4ODNiNmY3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ1OTA1Nzk5OTk5OTk2LC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWVmOGRmYzc3MWJjNDdmNjg3ZGEzMDA3YzhlY2E5OTMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODExM2U5YmU5MWNjNDE5MWJmNTVhMzE4NTE2N2U1YWEgPSAkKCc8ZGl2IGlkPSJodG1sXzgxMTNlOWJlOTFjYzQxOTFiZjU1YTMxODUxNjdlNWFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb24gTWlsbHMgTm9ydGgsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FlZjhkZmM3NzFiYzQ3ZjY4N2RhMzAwN2M4ZWNhOTkzLnNldENvbnRlbnQoaHRtbF84MTEzZTliZTkxY2M0MTkxYmY1NWEzMTg1MTY3ZTVhYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xYmQ2YTA5MjRhYWU0NjQ5YTQwMzcxYWZlODgzYjZmNy5iaW5kUG9wdXAocG9wdXBfYWVmOGRmYzc3MWJjNDdmNjg3ZGEzMDA3YzhlY2E5OTMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNmYyYjEyMzVkMzk5NDhhMGEyYjgxNTM0MmE2ODBhZDggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjU4OTk3MDAwMDAwMSwtNzkuMzQwOTIzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FlZDA0NjFlNGMwNTQ1M2VhYTJlYzcyMmQxMTBhZGRiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2NhNTE3MDhkZWNmYzQ2OGU4Yjc2OGU1ODc5NDcyMTc5ID0gJCgnPGRpdiBpZD0iaHRtbF9jYTUxNzA4ZGVjZmM0NjhlOGI3NjhlNTg3OTQ3MjE3OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmxlbWluZ2RvbiBQYXJrRG9uIE1pbGxzIFNvdXRoLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hZWQwNDYxZTRjMDU0NTNlYWEyZWM3MjJkMTEwYWRkYi5zZXRDb250ZW50KGh0bWxfY2E1MTcwOGRlY2ZjNDY4ZThiNzY4ZTU4Nzk0NzIxNzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNmYyYjEyMzVkMzk5NDhhMGEyYjgxNTM0MmE2ODBhZDguYmluZFBvcHVwKHBvcHVwX2FlZDA0NjFlNGMwNTQ1M2VhYTJlYzcyMmQxMTBhZGRiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzAwMWE4ODIxZDNmMjRiOWU4MTMyN2U2MTIwMTIyYjJhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU0MzI4MywtNzkuNDQyMjU5M10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kZDhmZTQwZTdhYTY0MzgwOGE5NGU5MjA2ZjY0MDJmZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNDgwMzBlMzJhNDU0MTQ0YTg3NzJiM2YyZGFiMDIzNSA9ICQoJzxkaXYgaWQ9Imh0bWxfMTQ4MDMwZTMyYTQ1NDE0NGE4NzcyYjNmMmRhYjAyMzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJhdGh1cnN0IE1hbm9yRG93bnN2aWV3IE5vcnRoV2lsc29uIEhlaWdodHMsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RkOGZlNDBlN2FhNjQzODA4YTk0ZTkyMDZmNjQwMmZlLnNldENvbnRlbnQoaHRtbF8xNDgwMzBlMzJhNDU0MTQ0YTg3NzJiM2YyZGFiMDIzNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wMDFhODgyMWQzZjI0YjllODEzMjdlNjEyMDEyMmIyYS5iaW5kUG9wdXAocG9wdXBfZGQ4ZmU0MGU3YWE2NDM4MDhhOTRlOTIwNmY2NDAyZmUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTJlNmYyNTBhNzcyNDRkZmFkMGJlOTA4OGI2OWI2NWUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Njc5ODAzLC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hYzA5NmE4ZGQ2MTc0ZGIwYTQ2YjNiMjNmMGUyMTFiNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMDdhYmM4MDMyZDg0ODMzODU2MzU1OGY3YTliOTQ3OSA9ICQoJzxkaXYgaWQ9Imh0bWxfZjA3YWJjODAzMmQ4NDgzMzg1NjM1NThmN2E5Yjk0NzkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRod29vZCBQYXJrWW9yayBVbml2ZXJzaXR5LCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hYzA5NmE4ZGQ2MTc0ZGIwYTQ2YjNiMjNmMGUyMTFiNC5zZXRDb250ZW50KGh0bWxfZjA3YWJjODAzMmQ4NDgzMzg1NjM1NThmN2E5Yjk0NzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTJlNmYyNTBhNzcyNDRkZmFkMGJlOTA4OGI2OWI2NWUuYmluZFBvcHVwKHBvcHVwX2FjMDk2YThkZDYxNzRkYjBhNDZiM2IyM2YwZTIxMWI0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI5NDc3Yjc2YjE1ZjRkMTNhOTUwOWJhNzhlMDYzYWM1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM3NDczMjAwMDAwMDA0LC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yMGIyZWUzNzU2MmI0NmY2ODBiZjc4ZDc5MDZkZjg5MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNGRkODM0NDVjNzc0YTQ1ODU4NGNhNmZhZTU3OGUwZCA9ICQoJzxkaXYgaWQ9Imh0bWxfMzRkZDgzNDQ1Yzc3NGE0NTg1ODRjYTZmYWU1NzhlMGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNGQiBUb3JvbnRvRG93bnN2aWV3IEVhc3QsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzIwYjJlZTM3NTYyYjQ2ZjY4MGJmNzhkNzkwNmRmODkwLnNldENvbnRlbnQoaHRtbF8zNGRkODM0NDVjNzc0YTQ1ODU4NGNhNmZhZTU3OGUwZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yOTQ3N2I3NmIxNWY0ZDEzYTk1MDliYTc4ZTA2M2FjNS5iaW5kUG9wdXAocG9wdXBfMjBiMmVlMzc1NjJiNDZmNjgwYmY3OGQ3OTA2ZGY4OTApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWQ0NGM2MmI3OTcxNDUxYmExMjY5ZTYxZjg5NDk0NzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzkwMTQ2LC03OS41MDY5NDM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ0N2M2MmFjODEzNjQxYzZiZmY1ZjA1N2I5MjhmMGMwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzU1MDc5MmYxOGZiODQ0MDdhOWYwZGJlYTM0OWVjYThmID0gJCgnPGRpdiBpZD0iaHRtbF81NTA3OTJmMThmYjg0NDA3YTlmMGRiZWEzNDllY2E4ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3IFdlc3QsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ0N2M2MmFjODEzNjQxYzZiZmY1ZjA1N2I5MjhmMGMwLnNldENvbnRlbnQoaHRtbF81NTA3OTJmMThmYjg0NDA3YTlmMGRiZWEzNDllY2E4Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hZDQ0YzYyYjc5NzE0NTFiYTEyNjllNjFmODk0OTQ3MS5iaW5kUG9wdXAocG9wdXBfNDQ3YzYyYWM4MTM2NDFjNmJmZjVmMDU3YjkyOGYwYzApOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDcyMjczY2E0YTkxNDZjY2I0NTZkNjkxNWVjNzZjZjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjg0OTY0LC03OS40OTU2OTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mMTQ2ZmMwMGQ2OTE0NzNjOGQ0ODBhZmE5ZDkzYTMzNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85YjE2YWQxNDE2ZGI0ZjkzOTU5NzFlOTc2ZGYxZjgwZiA9ICQoJzxkaXYgaWQ9Imh0bWxfOWIxNmFkMTQxNmRiNGY5Mzk1OTcxZTk3NmRmMWY4MGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBDZW50cmFsLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mMTQ2ZmMwMGQ2OTE0NzNjOGQ0ODBhZmE5ZDkzYTMzNy5zZXRDb250ZW50KGh0bWxfOWIxNmFkMTQxNmRiNGY5Mzk1OTcxZTk3NmRmMWY4MGYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDcyMjczY2E0YTkxNDZjY2I0NTZkNjkxNWVjNzZjZjEuYmluZFBvcHVwKHBvcHVwX2YxNDZmYzAwZDY5MTQ3M2M4ZDQ4MGFmYTlkOTNhMzM3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwOTFlMjc5ZTYzYzRmMWFhYzFkNjhmN2E1M2UxZTA1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYxNjMxMywtNzkuNTIwOTk5NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2ZjMjMxMWQwY2JjNDY5ODkxNmQzMzZlODE2ZDdlNjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmUzY2I2ZjExZDEyNGE4MGEyYzhlZTBiMmU5YjhlY2MgPSAkKCc8ZGl2IGlkPSJodG1sX2ZlM2NiNmYxMWQxMjRhODBhMmM4ZWUwYjJlOWI4ZWNjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgTm9ydGh3ZXN0LCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83ZmMyMzExZDBjYmM0Njk4OTE2ZDMzNmU4MTZkN2U2NS5zZXRDb250ZW50KGh0bWxfZmUzY2I2ZjExZDEyNGE4MGEyYzhlZTBiMmU5YjhlY2MpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjA5MWUyNzllNjNjNGYxYWFjMWQ2OGY3YTUzZTFlMDUuYmluZFBvcHVwKHBvcHVwXzdmYzIzMTFkMGNiYzQ2OTg5MTZkMzM2ZTgxNmQ3ZTY1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzk5ZDNkZmU2NWVjMTQzNzQ5ODEzNTZkOWRhM2VkOTNmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LC03OS4zMTU1NzE1OTk5OTk5OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85NTI3Y2NkZGY2ODc0ZTUwYWEyZDVlMjg2MTIwYmNiYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83OTU2NjZjMmI3ZDU0MWU1OTM1NTYzMjExMjQyYTU2MCA9ICQoJzxkaXYgaWQ9Imh0bWxfNzk1NjY2YzJiN2Q1NDFlNTkzNTU2MzIxMTI0MmE1NjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlZpY3RvcmlhIFZpbGxhZ2UsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk1MjdjY2RkZjY4NzRlNTBhYTJkNWUyODYxMjBiY2JjLnNldENvbnRlbnQoaHRtbF83OTU2NjZjMmI3ZDU0MWU1OTM1NTYzMjExMjQyYTU2MCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85OWQzZGZlNjVlYzE0Mzc0OTgxMzU2ZDlkYTNlZDkzZi5iaW5kUG9wdXAocG9wdXBfOTUyN2NjZGRmNjg3NGU1MGFhMmQ1ZTI4NjEyMGJjYmMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDBmZGJlMDFiYTFlNDk1MzkyMTlhYjg3MTY5NTlhM2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDYzOTcyLC03OS4zMDk5MzddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjAyMGQwOTE1NmFkNDg4MmIzZTRlYmQwOTRhMGMxNmEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjUxNGUwZDkwOTAxNDRhZTgxNmQ4ZTY0NDFkY2QyMjIgPSAkKCc8ZGl2IGlkPSJodG1sXzY1MTRlMGQ5MDkwMTQ0YWU4MTZkOGU2NDQxZGNkMjIyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBHYXJkZW5zUGFya3ZpZXcgSGlsbCwgRWFzdCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yMDIwZDA5MTU2YWQ0ODgyYjNlNGViZDA5NGEwYzE2YS5zZXRDb250ZW50KGh0bWxfNjUxNGUwZDkwOTAxNDRhZTgxNmQ4ZTY0NDFkY2QyMjIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDBmZGJlMDFiYTFlNDk1MzkyMTlhYjg3MTY5NTlhM2EuYmluZFBvcHVwKHBvcHVwXzIwMjBkMDkxNTZhZDQ4ODJiM2U0ZWJkMDk0YTBjMTZhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY5OWU5YjczMzQzMDRkM2M4YjU1ZTYxMDIzZmU3YzhhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk1MzQzOTAwMDAwMDA1LC03OS4zMTgzODg3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzViNWZkNDVhNTBhMDQ5NzE5NzI3YTY1ZmNkYTY1M2I0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2YxZjU0NmUyNGVmNTQzOGJhMjY2NDYxMjFiOTFlMmM5ID0gJCgnPGRpdiBpZD0iaHRtbF9mMWY1NDZlMjRlZjU0MzhiYTI2NjQ2MTIxYjkxZTJjOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29vZGJpbmUgSGVpZ2h0cywgRWFzdCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81YjVmZDQ1YTUwYTA0OTcxOTcyN2E2NWZjZGE2NTNiNC5zZXRDb250ZW50KGh0bWxfZjFmNTQ2ZTI0ZWY1NDM4YmEyNjY0NjEyMWI5MWUyYzkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjk5ZTliNzMzNDMwNGQzYzhiNTVlNjEwMjNmZTdjOGEuYmluZFBvcHVwKHBvcHVwXzViNWZkNDVhNTBhMDQ5NzE5NzI3YTY1ZmNkYTY1M2I0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNlODkyNDVhZDQ5NjRhNzA5NTE2NGI3ZDZmMjA2YTU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc2MzU3Mzk5OTk5OTksLTc5LjI5MzAzMTJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTMyN2NjNjMyOTVmNDAwNTk1ZDM3ZTJmMWE2ZTI4YjkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWIwMDU4MTcyNGNkNGMyMzk0YjExZDQxOTExZGQwMDQgPSAkKCc8ZGl2IGlkPSJodG1sX2ViMDA1ODE3MjRjZDRjMjM5NGIxMWQ0MTkxMWRkMDA0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcywgRWFzdCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81MzI3Y2M2MzI5NWY0MDA1OTVkMzdlMmYxYTZlMjhiOS5zZXRDb250ZW50KGh0bWxfZWIwMDU4MTcyNGNkNGMyMzk0YjExZDQxOTExZGQwMDQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2U4OTI0NWFkNDk2NGE3MDk1MTY0YjdkNmYyMDZhNTUuYmluZFBvcHVwKHBvcHVwXzUzMjdjYzYzMjk1ZjQwMDU5NWQzN2UyZjFhNmUyOGI5KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q0NzlmNmNmNDlhNTRjMmU4ODgzOGZhNTU3YzdmNWRmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA5MDYwNCwtNzkuMzYzNDUxN10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85ZjliMGY5MDcyNmE0Nzk4YmM2ZGZkOGQ5NzcyZjkxZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lYTZlODJhZTM0M2Q0NDQzYTA5NGQ5ZjYxNzcyMWU5OCA9ICQoJzxkaXYgaWQ9Imh0bWxfZWE2ZTgyYWUzNDNkNDQ0M2EwOTRkOWY2MTc3MjFlOTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxlYXNpZGUsIEVhc3QgWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOWY5YjBmOTA3MjZhNDc5OGJjNmRmZDhkOTc3MmY5MWUuc2V0Q29udGVudChodG1sX2VhNmU4MmFlMzQzZDQ0NDNhMDk0ZDlmNjE3NzIxZTk4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Q0NzlmNmNmNDlhNTRjMmU4ODgzOGZhNTU3YzdmNWRmLmJpbmRQb3B1cChwb3B1cF85ZjliMGY5MDcyNmE0Nzk4YmM2ZGZkOGQ5NzcyZjkxZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84OWNhYjY1MTU5NmU0MzQ3OWE4MmEzZjBiZWQyY2Q0OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNTM2ODksLTc5LjM0OTM3MTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg0NWNlMWJjMGE4MTQxOTFhYTZlMTRhMDUxZGU1MjI2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNhYTE2ZGM2Nzk0NDRlYjU4YzMzZmFhYmI4YzE4MGUxID0gJCgnPGRpdiBpZD0iaHRtbF8zYWExNmRjNjc5NDQ0ZWI1OGMzM2ZhYWJiOGMxODBlMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhvcm5jbGlmZmUgUGFyaywgRWFzdCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NDVjZTFiYzBhODE0MTkxYWE2ZTE0YTA1MWRlNTIyNi5zZXRDb250ZW50KGh0bWxfM2FhMTZkYzY3OTQ0NGViNThjMzNmYWFiYjhjMTgwZTEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODljYWI2NTE1OTZlNDM0NzlhODJhM2YwYmVkMmNkNDguYmluZFBvcHVwKHBvcHVwXzg0NWNlMWJjMGE4MTQxOTFhYTZlMTRhMDUxZGU1MjI2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY3NWVmNjY2MTNmZjRlOGE4YjliMmRjY2Q2MDNlZTJmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg1MzQ3LC03OS4zMzgxMDY1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNmMjUyMTFhY2FiMDQxZGE5OTk2MDk2MWI3YmZlNmFlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VjYmNjY2MwMmIzMjRkZmU5NzI2YWVmMzRmOGNmZjA5ID0gJCgnPGRpdiBpZD0iaHRtbF9lY2JjY2NjMDJiMzI0ZGZlOTcyNmFlZjM0ZjhjZmYwOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RWFzdCBUb3JvbnRvLCBFYXN0IFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzNmMjUyMTFhY2FiMDQxZGE5OTk2MDk2MWI3YmZlNmFlLnNldENvbnRlbnQoaHRtbF9lY2JjY2NjMDJiMzI0ZGZlOTcyNmFlZjM0ZjhjZmYwOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82NzVlZjY2NjEzZmY0ZThhOGI5YjJkY2NkNjAzZWUyZi5iaW5kUG9wdXAocG9wdXBfM2YyNTIxMWFjYWIwNDFkYTk5OTYwOTYxYjdiZmU2YWUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjAxMjY2Zjk5MzdlNDMwMTkzMjEyNDJhM2QxZTg5YWYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Nzk1NTcxLC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGU1NzViZDA1ZTk5NGNhZGJiYzVlZTI2NjQ5ZDgxODcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjczNGU3ODA2OWY2NDVjYWJhN2I5MzllZmY5OGE2NDcgPSAkKCc8ZGl2IGlkPSJodG1sXzI3MzRlNzgwNjlmNjQ1Y2FiYTdiOTM5ZWZmOThhNjQ3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgRGFuZm9ydGggV2VzdFJpdmVyZGFsZSwgRWFzdCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84ZTU3NWJkMDVlOTk0Y2FkYmJjNWVlMjY2NDlkODE4Ny5zZXRDb250ZW50KGh0bWxfMjczNGU3ODA2OWY2NDVjYWJhN2I5MzllZmY5OGE2NDcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjAxMjY2Zjk5MzdlNDMwMTkzMjEyNDJhM2QxZTg5YWYuYmluZFBvcHVwKHBvcHVwXzhlNTc1YmQwNWU5OTRjYWRiYmM1ZWUyNjY0OWQ4MTg3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NlMzVhNTg4YTRmZjQ0MmRhMDViOGQ0OTczNDRhZWNhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY4OTk4NSwtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2FlMjVhYWU5OTQxNDEwMDljZGMwYTU1N2Y5MmVjYTUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzg2ZGU5YjUzYjhhNDc3OTkwODc0Y2FjMGY5ZGU2NTkgPSAkKCc8ZGl2IGlkPSJodG1sXzM4NmRlOWI1M2I4YTQ3Nzk5MDg3NGNhYzBmOWRlNjU5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcyBXZXN0SW5kaWEgQmF6YWFyLCBFYXN0IFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzNhZTI1YWFlOTk0MTQxMDA5Y2RjMGE1NTdmOTJlY2E1LnNldENvbnRlbnQoaHRtbF8zODZkZTliNTNiOGE0Nzc5OTA4NzRjYWMwZjlkZTY1OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jZTM1YTU4OGE0ZmY0NDJkYTA1YjhkNDk3MzQ0YWVjYS5iaW5kUG9wdXAocG9wdXBfM2FlMjVhYWU5OTQxNDEwMDljZGMwYTU1N2Y5MmVjYTUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjc3ZDBhMDdiNjI3NGZjNTljNzQzN2Q2OTQ3YjZhY2IgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTk1MjU1LC03OS4zNDA5MjNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNGJjNDUzY2ZhZDMyNDNhNGI4NzBjODcwZThjZjUwZDAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODI3YTRmNWY1YjhkNGEzZjk2OTZiOTNhMjVmMGM3ZjIgPSAkKCc8ZGl2IGlkPSJodG1sXzgyN2E0ZjVmNWI4ZDRhM2Y5Njk2YjkzYTI1ZjBjN2YyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdHVkaW8gRGlzdHJpY3QsIEVhc3QgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGJjNDUzY2ZhZDMyNDNhNGI4NzBjODcwZThjZjUwZDAuc2V0Q29udGVudChodG1sXzgyN2E0ZjVmNWI4ZDRhM2Y5Njk2YjkzYTI1ZjBjN2YyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzI3N2QwYTA3YjYyNzRmYzU5Yzc0MzdkNjk0N2I2YWNiLmJpbmRQb3B1cChwb3B1cF80YmM0NTNjZmFkMzI0M2E0Yjg3MGM4NzBlOGNmNTBkMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMjMwN2Q2ZDAyZTU0MmEwYWYwZjk5YTI4MTA1NGZjOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyODAyMDUsLTc5LjM4ODc5MDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGNkOTgxMTU3MjNhNDE3ZDg1ZDhlZjVlYzFiMTA2YWEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGUyOWY5MTE5MmQ1NGI2OWIzZTZlNzkxOTM2MWFmNmIgPSAkKCc8ZGl2IGlkPSJodG1sX2RlMjlmOTExOTJkNTRiNjliM2U2ZTc5MTkzNjFhZjZiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MYXdyZW5jZSBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RjZDk4MTE1NzIzYTQxN2Q4NWQ4ZWY1ZWMxYjEwNmFhLnNldENvbnRlbnQoaHRtbF9kZTI5ZjkxMTkyZDU0YjY5YjNlNmU3OTE5MzYxYWY2Yik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lMjMwN2Q2ZDAyZTU0MmEwYWYwZjk5YTI4MTA1NGZjOC5iaW5kUG9wdXAocG9wdXBfZGNkOTgxMTU3MjNhNDE3ZDg1ZDhlZjVlYzFiMTA2YWEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzZkMDIxOGZlNjI5NGE3YWJlMWM2MjE0ZjhhOGQyNmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTI3NTExLC03OS4zOTAxOTc1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzY3NmVkMGIxYjIzNTQ0ODM4YzlhOGI2OTRiZWE5OTQ1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZlMmMzMTJhNzk0OTQ3NDJiM2VhZmMzMzY1NTY1OTM4ID0gJCgnPGRpdiBpZD0iaHRtbF9mZTJjMzEyYTc5NDk0NzQyYjNlYWZjMzM2NTU2NTkzOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGF2aXN2aWxsZSBOb3J0aCwgQ2VudHJhbCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82NzZlZDBiMWIyMzU0NDgzOGM5YThiNjk0YmVhOTk0NS5zZXRDb250ZW50KGh0bWxfZmUyYzMxMmE3OTQ5NDc0MmIzZWFmYzMzNjU1NjU5MzgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzZkMDIxOGZlNjI5NGE3YWJlMWM2MjE0ZjhhOGQyNmIuYmluZFBvcHVwKHBvcHVwXzY3NmVkMGIxYjIzNTQ0ODM4YzlhOGI2OTRiZWE5OTQ1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjN2Q0Y2QyODhkMDQyZWI5YzhiMmI4MDA3NWQxMTM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE1MzgzNCwtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTJmOTA0NGRjYzhjNDU5NDhkMmMyZGE3YjVlYTA5OTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzE5MWM2NmVlMjA0NDVlYTk0NzNmNTgzYzk0OTBhZGIgPSAkKCc8ZGl2IGlkPSJodG1sXzcxOTFjNjZlZTIwNDQ1ZWE5NDczZjU4M2M5NDkwYWRiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBUb3JvbnRvIFdlc3QsIENlbnRyYWwgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTJmOTA0NGRjYzhjNDU5NDhkMmMyZGE3YjVlYTA5OTQuc2V0Q29udGVudChodG1sXzcxOTFjNjZlZTIwNDQ1ZWE5NDczZjU4M2M5NDkwYWRiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2NjN2Q0Y2QyODhkMDQyZWI5YzhiMmI4MDA3NWQxMTM0LmJpbmRQb3B1cChwb3B1cF9hMmY5MDQ0ZGNjOGM0NTk0OGQyYzJkYTdiNWVhMDk5NCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xMTNhMDgyNDJhMmY0MTA1ODhlNTE2NWQ5MzBkYzdmMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNDMyNDQsLTc5LjM4ODc5MDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2EyNjBjYjk4ZjY1NGZmZTlhNjYxMmYyYmFjM2VlYzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTE3Nzc3OGVlZTE3NDI5NWEwZDIxYWI2ZDc5MDQxOGMgPSAkKCc8ZGl2IGlkPSJodG1sX2UxNzc3NzhlZWUxNzQyOTVhMGQyMWFiNmQ3OTA0MThjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlLCBDZW50cmFsIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2NhMjYwY2I5OGY2NTRmZmU5YTY2MTJmMmJhYzNlZWMyLnNldENvbnRlbnQoaHRtbF9lMTc3Nzc4ZWVlMTc0Mjk1YTBkMjFhYjZkNzkwNDE4Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xMTNhMDgyNDJhMmY0MTA1ODhlNTE2NWQ5MzBkYzdmMC5iaW5kUG9wdXAocG9wdXBfY2EyNjBjYjk4ZjY1NGZmZTlhNjYxMmYyYmFjM2VlYzIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTdlN2U3MDVmNGE4NDkwYzgwYTE3ZjRjNDUzZjM1YzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODk1NzQzLC03OS4zODMxNTk5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83ZGM3ZjVlYThlNjM0OWM5OWY0ZDk4YTdjMjA0MDk5ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZWI0ZmU1MDlhYmE0NDU4YjdiZTA1NTUwZGU4YjU3MSA9ICQoJzxkaXYgaWQ9Imh0bWxfZGViNGZlNTA5YWJhNDQ1OGI3YmUwNTU1MGRlOGI1NzEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1vb3JlIFBhcmtTdW1tZXJoaWxsIEVhc3QsIENlbnRyYWwgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2RjN2Y1ZWE4ZTYzNDljOTlmNGQ5OGE3YzIwNDA5OWYuc2V0Q29udGVudChodG1sX2RlYjRmZTUwOWFiYTQ0NThiN2JlMDU1NTBkZThiNTcxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2U3ZTdlNzA1ZjRhODQ5MGM4MGExN2Y0YzQ1M2YzNWM3LmJpbmRQb3B1cChwb3B1cF83ZGM3ZjVlYThlNjM0OWM5OWY0ZDk4YTdjMjA0MDk5Zik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lZDAzOTRlZjg4ODU0MWMwOTBlYmE1NGJjNTAxYzRjYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4NjQxMjI5OTk5OTk5LC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E3YTM1N2M1NDVmMTRiOTBiOTc3MDQ5MGFlZWRhZDIxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk4MmQzNDA2ZmIxNzRkMzc5Mzg3OWFlNDllOTAyYzQzID0gJCgnPGRpdiBpZD0iaHRtbF85ODJkMzQwNmZiMTc0ZDM3OTM4NzlhZTQ5ZTkwMmM0MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RGVlciBQYXJrRm9yZXN0IEhpbGwgU0VSYXRobmVsbHlTb3V0aCBIaWxsU3VtbWVyaGlsbCBXZXN0LCBDZW50cmFsIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E3YTM1N2M1NDVmMTRiOTBiOTc3MDQ5MGFlZWRhZDIxLnNldENvbnRlbnQoaHRtbF85ODJkMzQwNmZiMTc0ZDM3OTM4NzlhZTQ5ZTkwMmM0Myk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lZDAzOTRlZjg4ODU0MWMwOTBlYmE1NGJjNTAxYzRjYS5iaW5kUG9wdXAocG9wdXBfYTdhMzU3YzU0NWYxNGI5MGI5NzcwNDkwYWVlZGFkMjEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWE3MzUxOTZhNWZlNGE3ZGE0YTE2MmNhOTY1MWVhNWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Nzk1NjI2LC03OS4zNzc1Mjk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83OTU0OTY4ODY3YzA0YWE0YTQ4NmQzZjA0MmRhMTk1MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80YWVlNDNhZGQ0ZTU0NTcwOWNiN2JkYmFkNzYxOTY3MyA9ICQoJzxkaXYgaWQ9Imh0bWxfNGFlZTQzYWRkNGU1NDU3MDljYjdiZGJhZDc2MTk2NzMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VkYWxlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83OTU0OTY4ODY3YzA0YWE0YTQ4NmQzZjA0MmRhMTk1My5zZXRDb250ZW50KGh0bWxfNGFlZTQzYWRkNGU1NDU3MDljYjdiZGJhZDc2MTk2NzMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNWE3MzUxOTZhNWZlNGE3ZGE0YTE2MmNhOTY1MWVhNWIuYmluZFBvcHVwKHBvcHVwXzc5NTQ5Njg4NjdjMDRhYTRhNDg2ZDNmMDQyZGExOTUzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzMxY2QzMTI1NTg5YzQzMTQ5MjRlMTc3MWUwNTY3NTA0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY3OTY3LC03OS4zNjc2NzUzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMzNGE5ZDc0YmQ1MTRjNTk5MzE1ODc2NDY2YThmODNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUyNzdmYjkyYmYxMjQ2OWNhODFkMzRlNGU0OGUyMjYxID0gJCgnPGRpdiBpZD0iaHRtbF81Mjc3ZmI5MmJmMTI0NjljYTgxZDM0ZTRlNDhlMjI2MSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FiYmFnZXRvd25TdC4gSmFtZXMgVG93biwgRG93bnRvd24gVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzM0YTlkNzRiZDUxNGM1OTkzMTU4NzY0NjZhOGY4M2Quc2V0Q29udGVudChodG1sXzUyNzdmYjkyYmYxMjQ2OWNhODFkMzRlNGU0OGUyMjYxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzMxY2QzMTI1NTg5YzQzMTQ5MjRlMTc3MWUwNTY3NTA0LmJpbmRQb3B1cChwb3B1cF8zMzRhOWQ3NGJkNTE0YzU5OTMxNTg3NjQ2NmE4ZjgzZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wNzMxNDEwMjQ1ZTI0MzczOGI3MTUyOGFkZDc3MmIwMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2NTg1OTksLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2YyM2ZkYzkwMDI3MTRiZjJiNWYwMDhjM2RhODdiMTc1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRhOGY4Zjc0OGY3MDRkNTZhZTQ2NGI1MThjZWYyZWM3ID0gJCgnPGRpdiBpZD0iaHRtbF80YThmOGY3NDhmNzA0ZDU2YWU0NjRiNTE4Y2VmMmVjNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2h1cmNoIGFuZCBXZWxsZXNsZXksIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2YyM2ZkYzkwMDI3MTRiZjJiNWYwMDhjM2RhODdiMTc1LnNldENvbnRlbnQoaHRtbF80YThmOGY3NDhmNzA0ZDU2YWU0NjRiNTE4Y2VmMmVjNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wNzMxNDEwMjQ1ZTI0MzczOGI3MTUyOGFkZDc3MmIwMi5iaW5kUG9wdXAocG9wdXBfZjIzZmRjOTAwMjcxNGJmMmI1ZjAwOGMzZGE4N2IxNzUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODBkZGE0OWY3MTkwNGVhOTk5Y2E3NjkxYmQxZDk5ZTMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTQyNTk5LC03OS4zNjA2MzU5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FiZmQ3YjAzMmI3ZTQ3N2U5YjM2ZjQ2MWVlYWQzOGRhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk3MmI5Yzc0ZDBkOTQwOWQ5MWE1MzQwMjE3MWYxMzkyID0gJCgnPGRpdiBpZD0iaHRtbF85NzJiOWM3NGQwZDk0MDlkOTFhNTM0MDIxNzFmMTM5MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250UmVnZW50IFBhcmssIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FiZmQ3YjAzMmI3ZTQ3N2U5YjM2ZjQ2MWVlYWQzOGRhLnNldENvbnRlbnQoaHRtbF85NzJiOWM3NGQwZDk0MDlkOTFhNTM0MDIxNzFmMTM5Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84MGRkYTQ5ZjcxOTA0ZWE5OTljYTc2OTFiZDFkOTllMy5iaW5kUG9wdXAocG9wdXBfYWJmZDdiMDMyYjdlNDc3ZTliMzZmNDYxZWVhZDM4ZGEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGQyYjVjNzVmZjdiNGUxNDkyNTQwNDA1OGRjN2YwNzMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTcxNjE4LC03OS4zNzg5MzcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYmJiMzU1ZWUwMGY0NTYxYmVlMTRhMDgzMGU0OTc0NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kOTUzOTY4YTg5MDM0MjAzOGVlZWQ3YTYwYmRmNTEyNyA9ICQoJzxkaXYgaWQ9Imh0bWxfZDk1Mzk2OGE4OTAzNDIwMzhlZWVkN2E2MGJkZjUxMjciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJ5ZXJzb25HYXJkZW4gRGlzdHJpY3QsIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RiYmIzNTVlZTAwZjQ1NjFiZWUxNGEwODMwZTQ5NzQ2LnNldENvbnRlbnQoaHRtbF9kOTUzOTY4YTg5MDM0MjAzOGVlZWQ3YTYwYmRmNTEyNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84ZDJiNWM3NWZmN2I0ZTE0OTI1NDA0MDU4ZGM3ZjA3My5iaW5kUG9wdXAocG9wdXBfZGJiYjM1NWVlMDBmNDU2MWJlZTE0YTA4MzBlNDk3NDYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGU5NzFmMjc4ZDlhNDgwN2FjZjg5NDE5ZGE3ZjVkMDEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTE0OTM5LC03OS4zNzU0MTc5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJlMzUzNmEyNTkzYTQ2Mzg4ZWYzZWI5NmIyMzMwZDBkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZkMzdhNWE0N2FiODQxYjk5N2FhMzYyYzhjODUxODhlID0gJCgnPGRpdiBpZD0iaHRtbF9mZDM3YTVhNDdhYjg0MWI5OTdhYTM2MmM4Yzg1MTg4ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3QuIEphbWVzIFRvd24sIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzJlMzUzNmEyNTkzYTQ2Mzg4ZWYzZWI5NmIyMzMwZDBkLnNldENvbnRlbnQoaHRtbF9mZDM3YTVhNDdhYjg0MWI5OTdhYTM2MmM4Yzg1MTg4ZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kZTk3MWYyNzhkOWE0ODA3YWNmODk0MTlkYTdmNWQwMS5iaW5kUG9wdXAocG9wdXBfMmUzNTM2YTI1OTNhNDYzODhlZjNlYjk2YjIzMzBkMGQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWNhYTNlODFkOTI4NDM4MmFkMmUxZWM1ZDIzMDRmNjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDQ3NzA3OTk5OTk5OTYsLTc5LjM3MzMwNjRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDNhMGRhMWQ4MGFhNGUxNTgzODZjOWIwNGEyN2ZjYWQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGEyY2ZmMmRkMWE2NDUyMjhkNTczMDE3NTMwMDg1ZWYgPSAkKCc8ZGl2IGlkPSJodG1sXzRhMmNmZjJkZDFhNjQ1MjI4ZDU3MzAxNzUzMDA4NWVmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CZXJjenkgUGFyaywgRG93bnRvd24gVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDNhMGRhMWQ4MGFhNGUxNTgzODZjOWIwNGEyN2ZjYWQuc2V0Q29udGVudChodG1sXzRhMmNmZjJkZDFhNjQ1MjI4ZDU3MzAxNzUzMDA4NWVmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFjYWEzZTgxZDkyODQzODJhZDJlMWVjNWQyMzA0ZjY2LmJpbmRQb3B1cChwb3B1cF8wM2EwZGExZDgwYWE0ZTE1ODM4NmM5YjA0YTI3ZmNhZCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yYjY2ZjVmMWVjYTY0YzZiOTVjNWJiZjRkYjE5MzU5YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1Nzk1MjQsLTc5LjM4NzM4MjZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmJlYjY3MmZkNjQ0NDc2MmIwYWYzMDA5OTM5YzNiNTUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNmU0MjNjZWMwOTI3NGJjY2IyZmFjYzEwNDEyZDdjNzggPSAkKCc8ZGl2IGlkPSJodG1sXzZlNDIzY2VjMDkyNzRiY2NiMmZhY2MxMDQxMmQ3Yzc4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZW50cmFsIEJheSBTdHJlZXQsIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzJiZWI2NzJmZDY0NDQ3NjJiMGFmMzAwOTkzOWMzYjU1LnNldENvbnRlbnQoaHRtbF82ZTQyM2NlYzA5Mjc0YmNjYjJmYWNjMTA0MTJkN2M3OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yYjY2ZjVmMWVjYTY0YzZiOTVjNWJiZjRkYjE5MzU5YS5iaW5kUG9wdXAocG9wdXBfMmJlYjY3MmZkNjQ0NDc2MmIwYWYzMDA5OTM5YzNiNTUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzI2NGI3MWYxNDQzNDhlNWEwNzNhNmMzMTI5ZDIzMzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTA1NzEyMDAwMDAwMSwtNzkuMzg0NTY3NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wYmFmMWM1YmNiOWY0MWVlYWQ2YWU1NzgzZGE2NTllMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83ZmJmOWMxM2QzNDE0MjY1OGQ5NGZkZjZjZTc3ZTQxYiA9ICQoJzxkaXYgaWQ9Imh0bWxfN2ZiZjljMTNkMzQxNDI2NThkOTRmZGY2Y2U3N2U0MWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFkZWxhaWRlS2luZ1JpY2htb25kLCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wYmFmMWM1YmNiOWY0MWVlYWQ2YWU1NzgzZGE2NTllMS5zZXRDb250ZW50KGh0bWxfN2ZiZjljMTNkMzQxNDI2NThkOTRmZGY2Y2U3N2U0MWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzI2NGI3MWYxNDQzNDhlNWEwNzNhNmMzMTI5ZDIzMzcuYmluZFBvcHVwKHBvcHVwXzBiYWYxYzViY2I5ZjQxZWVhZDZhZTU3ODNkYTY1OWUxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmZjRjODg2NWFlYjQxNmZiODQ2NDNiZTZjYmE4MDA2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQwODE1NywtNzkuMzgxNzUyMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTcwOGJmMWIyOTUzNDg0Yjg1NmFiNmEzYTBjMTI2Y2EgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmI1YzFmOGY1MWQzNDMyYzgwYzczZWFhMjQ0NjRmZDQgPSAkKCc8ZGl2IGlkPSJodG1sX2JiNWMxZjhmNTFkMzQzMmM4MGM3M2VhYTI0NDY0ZmQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IYXJib3VyZnJvbnQgRWFzdFRvcm9udG8gSXNsYW5kc1VuaW9uIFN0YXRpb24sIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU3MDhiZjFiMjk1MzQ4NGI4NTZhYjZhM2EwYzEyNmNhLnNldENvbnRlbnQoaHRtbF9iYjVjMWY4ZjUxZDM0MzJjODBjNzNlYWEyNDQ2NGZkNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85ZmY0Yzg4NjVhZWI0MTZmYjg0NjQzYmU2Y2JhODAwNi5iaW5kUG9wdXAocG9wdXBfNTcwOGJmMWIyOTUzNDg0Yjg1NmFiNmEzYTBjMTI2Y2EpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2Y0MmQ5ZTU1ZDQzNGU0MmEyNTkyZTZlYzMwZTJlMmUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDcxNzY4LC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81NTg1MjcxOTRjMGE0Y2U1YmFlNWVkNTcxYTI3ZDFjNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yODY2OTRkZDVlZmE0YmY4OTM2YWNmZjJiMzc2MGM5ZiA9ICQoJzxkaXYgaWQ9Imh0bWxfMjg2Njk0ZGQ1ZWZhNGJmODkzNmFjZmYyYjM3NjBjOWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlc2lnbiBFeGNoYW5nZVRvcm9udG8gRG9taW5pb24gQ2VudHJlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81NTg1MjcxOTRjMGE0Y2U1YmFlNWVkNTcxYTI3ZDFjNi5zZXRDb250ZW50KGh0bWxfMjg2Njk0ZGQ1ZWZhNGJmODkzNmFjZmYyYjM3NjBjOWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfY2Y0MmQ5ZTU1ZDQzNGU0MmEyNTkyZTZlYzMwZTJlMmUuYmluZFBvcHVwKHBvcHVwXzU1ODUyNzE5NGMwYTRjZTViYWU1ZWQ1NzFhMjdkMWM2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U0NzYzMmYwMGJjMTQ2ZDRhNzIzZGQyM2Y4MTEyOTU2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4MTk4NSwtNzkuMzc5ODE2OTAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmMxNDQ4MDAwMDJjNDY2YWFmMGVlNTAyNzc5NjZiYmQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjMyMTY2YjlkMmZhNDVhMDllYWEwYzc4NzEyYzU4NzQgPSAkKCc8ZGl2IGlkPSJodG1sXzYzMjE2NmI5ZDJmYTQ1YTA5ZWFhMGM3ODcxMmM1ODc0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db21tZXJjZSBDb3VydFZpY3RvcmlhIEhvdGVsLCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82YzE0NDgwMDAwMmM0NjZhYWYwZWU1MDI3Nzk2NmJiZC5zZXRDb250ZW50KGh0bWxfNjMyMTY2YjlkMmZhNDVhMDllYWEwYzc4NzEyYzU4NzQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTQ3NjMyZjAwYmMxNDZkNGE3MjNkZDIzZjgxMTI5NTYuYmluZFBvcHVwKHBvcHVwXzZjMTQ0ODAwMDAyYzQ2NmFhZjBlZTUwMjc3OTY2YmJkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UxNWIxNzdjNDk3MjQzZWQ5ZGVhNDQzYTA1ZmE5MjA1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzMzMjgyNSwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85NTczN2FiZmIwNjY0NDM1YTJkZWY4YTY3Y2U5MDM0OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85MDhjNDEwMTY1NTA0ZDFkOWQwYTczOGI4OWNlYjgxOCA9ICQoJzxkaXYgaWQ9Imh0bWxfOTA4YzQxMDE2NTUwNGQxZDlkMGE3MzhiODljZWI4MTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJlZGZvcmQgUGFya0xhd3JlbmNlIE1hbm9yIEVhc3QsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk1NzM3YWJmYjA2NjQ0MzVhMmRlZjhhNjdjZTkwMzQ4LnNldENvbnRlbnQoaHRtbF85MDhjNDEwMTY1NTA0ZDFkOWQwYTczOGI4OWNlYjgxOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lMTViMTc3YzQ5NzI0M2VkOWRlYTQ0M2EwNWZhOTIwNS5iaW5kUG9wdXAocG9wdXBfOTU3MzdhYmZiMDY2NDQzNWEyZGVmOGE2N2NlOTAzNDgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfN2Y3ZmMyNmUxZjg1NDZlNGEyZTRkZGFkMjcyM2IxYTYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTE2OTQ4LC03OS40MTY5MzU1OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MzI5MTQ1NWRhMzg0YmQ4OGUwNmNhM2FhMzhhNDIzNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81OGE5YzkwY2FhYzA0ZTcyOTRhMTg5YTI1MGNlMDBhYiA9ICQoJzxkaXYgaWQ9Imh0bWxfNThhOWM5MGNhYWMwNGU3Mjk0YTE4OWEyNTBjZTAwYWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VsYXduLCBDZW50cmFsIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzczMjkxNDU1ZGEzODRiZDg4ZTA2Y2EzYWEzOGE0MjM1LnNldENvbnRlbnQoaHRtbF81OGE5YzkwY2FhYzA0ZTcyOTRhMTg5YTI1MGNlMDBhYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83ZjdmYzI2ZTFmODU0NmU0YTJlNGRkYWQyNzIzYjFhNi5iaW5kUG9wdXAocG9wdXBfNzMyOTE0NTVkYTM4NGJkODhlMDZjYTNhYTM4YTQyMzUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWI2YmY4Zjk0OTI2NDg2NTgxYWNmZGZkZGE0YWI3NTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTY5NDc2LC03OS40MTEzMDcyMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mODYyMDcyMjBkMjY0ZTgwYWZlMWYyZGJjY2UxMDA2MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NGEyMzE0NTdmMWU0Mjc2OGYzODlmOWU1ODc2ODlkOCA9ICQoJzxkaXYgaWQ9Imh0bWxfNjRhMjMxNDU3ZjFlNDI3NjhmMzg5ZjllNTg3Njg5ZDgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZvcmVzdCBIaWxsIE5vcnRoRm9yZXN0IEhpbGwgV2VzdCwgQ2VudHJhbCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mODYyMDcyMjBkMjY0ZTgwYWZlMWYyZGJjY2UxMDA2My5zZXRDb250ZW50KGh0bWxfNjRhMjMxNDU3ZjFlNDI3NjhmMzg5ZjllNTg3Njg5ZDgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNWI2YmY4Zjk0OTI2NDg2NTgxYWNmZGZkZGE0YWI3NTQuYmluZFBvcHVwKHBvcHVwX2Y4NjIwNzIyMGQyNjRlODBhZmUxZjJkYmNjZTEwMDYzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIyNDhmMWVkOGFlYzQwNDE5ZjRjMmNjMjdhMGM4MDM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDJmNGNkNmE5ODQ4NDlmN2JjNzgxMDY5N2FmZTY0NTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGUyYmY2OTZhNzJmNGY2OThkN2FlODdhMjZlZjFhYmQgPSAkKCc8ZGl2IGlkPSJodG1sXzRlMmJmNjk2YTcyZjRmNjk4ZDdhZTg3YTI2ZWYxYWJkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQW5uZXhOb3J0aCBNaWR0b3duWW9ya3ZpbGxlLCBDZW50cmFsIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QyZjRjZDZhOTg0ODQ5ZjdiYzc4MTA2OTdhZmU2NDU2LnNldENvbnRlbnQoaHRtbF80ZTJiZjY5NmE3MmY0ZjY5OGQ3YWU4N2EyNmVmMWFiZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yMjQ4ZjFlZDhhZWM0MDQxOWY0YzJjYzI3YTBjODAzNC5iaW5kUG9wdXAocG9wdXBfZDJmNGNkNmE5ODQ4NDlmN2JjNzgxMDY5N2FmZTY0NTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjVlMTNjYzQ4NTIxNDBlNGFkYTg2YTc0YTA2ZmVhZmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjI2OTU2LC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RlODRhZjY0ODI2ODQ2MjE5MTkzMGIxYjdiMDljYWU0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ4NjYzOGFmZmViZDQ1MjliMTI3NmU1NjQ5OGMxMDkwID0gJCgnPGRpdiBpZD0iaHRtbF80ODY2MzhhZmZlYmQ0NTI5YjEyNzZlNTY0OThjMTA5MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm9yZFVuaXZlcnNpdHkgb2YgVG9yb250bywgRG93bnRvd24gVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZGU4NGFmNjQ4MjY4NDYyMTkxOTMwYjFiN2IwOWNhZTQuc2V0Q29udGVudChodG1sXzQ4NjYzOGFmZmViZDQ1MjliMTI3NmU1NjQ5OGMxMDkwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I1ZTEzY2M0ODUyMTQwZTRhZGE4NmE3NGEwNmZlYWZmLmJpbmRQb3B1cChwb3B1cF9kZTg0YWY2NDgyNjg0NjIxOTE5MzBiMWI3YjA5Y2FlNCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kYTI0MWNiOWFkOTI0NWVkOGRhZGFkMGUxZWY0OWRlMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzIwNTcsLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODkwMmFiMGNmMzRlNGY2ZTgwNDQ1NzQ1NjQwMWQzZGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDE2YTdhMzI4YzMyNDRlZDkyYzk1YjdkNWU5NmJlZGEgPSAkKCc8ZGl2IGlkPSJodG1sXzAxNmE3YTMyOGMzMjQ0ZWQ5MmM5NWI3ZDVlOTZiZWRhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaGluYXRvd25HcmFuZ2UgUGFya0tlbnNpbmd0b24gTWFya2V0LCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84OTAyYWIwY2YzNGU0ZjZlODA0NDU3NDU2NDAxZDNkZi5zZXRDb250ZW50KGh0bWxfMDE2YTdhMzI4YzMyNDRlZDkyYzk1YjdkNWU5NmJlZGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZGEyNDFjYjlhZDkyNDVlZDhkYWRhZDBlMWVmNDlkZTMuYmluZFBvcHVwKHBvcHVwXzg5MDJhYjBjZjM0ZTRmNmU4MDQ0NTc0NTY0MDFkM2RmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ5MTcxMmM4MTg5NjRlNzNiZDM2YmI2OTA1MmU5YzhiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4OTQ2NywtNzkuMzk0NDE5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xOTgzNjU4NTk2ODI0NDkwYmQ4YTFmMmE1ZTk5ZWE2YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZmFiODg4M2VjMDk0NjBiYjkwZmI4MzQyZDg5YzhkMyA9ICQoJzxkaXYgaWQ9Imh0bWxfM2ZhYjg4ODNlYzA5NDYwYmI5MGZiODM0MmQ4OWM4ZDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNOIFRvd2VyQmF0aHVyc3QgUXVheUlzbGFuZCBhaXJwb3J0SGFyYm91cmZyb250IFdlc3RLaW5nIGFuZCBTcGFkaW5hUmFpbHdheSBMYW5kc1NvdXRoIE5pYWdhcmEsIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzE5ODM2NTg1OTY4MjQ0OTBiZDhhMWYyYTVlOTllYTZjLnNldENvbnRlbnQoaHRtbF8zZmFiODg4M2VjMDk0NjBiYjkwZmI4MzQyZDg5YzhkMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80OTE3MTJjODE4OTY0ZTczYmQzNmJiNjkwNTJlOWM4Yi5iaW5kUG9wdXAocG9wdXBfMTk4MzY1ODU5NjgyNDQ5MGJkOGExZjJhNWU5OWVhNmMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDlhNjE4NmFlNjU1NDBlMDg5ODhlY2M2NTRkNDQyYTIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDY0MzUyLC03OS4zNzQ4NDU5OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hODQ5NGU1YTllNzQ0YjczOGE2N2NlNjk1YWRjMGFmYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hODE1MTViY2E5ZDA0N2RlOTMxMjhjZmFiNzIxNDI2MCA9ICQoJzxkaXYgaWQ9Imh0bWxfYTgxNTE1YmNhOWQwNDdkZTkzMTI4Y2ZhYjcyMTQyNjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0biBBIFBPIEJveGVzIDI1IFRoZSBFc3BsYW5hZGUsIERvd250b3duIFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E4NDk0ZTVhOWU3NDRiNzM4YTY3Y2U2OTVhZGMwYWZiLnNldENvbnRlbnQoaHRtbF9hODE1MTViY2E5ZDA0N2RlOTMxMjhjZmFiNzIxNDI2MCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80OWE2MTg2YWU2NTU0MGUwODk4OGVjYzY1NGQ0NDJhMi5iaW5kUG9wdXAocG9wdXBfYTg0OTRlNWE5ZTc0NGI3MzhhNjdjZTY5NWFkYzBhZmIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjViZGNlMzA5ODg3NGU5NWEwZjYwN2Y1Nzc4MTFiNDYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDg0MjkyLC03OS4zODIyODAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RlMDc3YTI5M2IwYjQ3YTQ4ZTk0OGVmMmVjMzkyOWQ2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VjZmE3YzJiNWQ0NTRlYzA4NjEzZmYxNjdhODE3YWZmID0gJCgnPGRpdiBpZD0iaHRtbF9lY2ZhN2MyYjVkNDU0ZWMwODYxM2ZmMTY3YTgxN2FmZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rmlyc3QgQ2FuYWRpYW4gUGxhY2VVbmRlcmdyb3VuZCBjaXR5LCBEb3dudG93biBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kZTA3N2EyOTNiMGI0N2E0OGU5NDhlZjJlYzM5MjlkNi5zZXRDb250ZW50KGh0bWxfZWNmYTdjMmI1ZDQ1NGVjMDg2MTNmZjE2N2E4MTdhZmYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjViZGNlMzA5ODg3NGU5NWEwZjYwN2Y1Nzc4MTFiNDYuYmluZFBvcHVwKHBvcHVwX2RlMDc3YTI5M2IwYjQ3YTQ4ZTk0OGVmMmVjMzkyOWQ2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI4MjMzZGFmYmQyZjRkMDliMzY5YmJiZjdkMzBjMWE0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE4NTE3OTk5OTk5OTk2LC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xODE2MmYzMWJmM2E0NjQyOWYwY2QxOWNjODFkMjdlMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84MTNlMmJiNWU1MzE0NmFkODI5Nzk5NWE2NDNjNzllMiA9ICQoJzxkaXYgaWQ9Imh0bWxfODEzZTJiYjVlNTMxNDZhZDgyOTc5OTVhNjQzYzc5ZTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIEhlaWdodHNMYXdyZW5jZSBNYW5vciwgTm9ydGggWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTgxNjJmMzFiZjNhNDY0MjlmMGNkMTljYzgxZDI3ZTEuc2V0Q29udGVudChodG1sXzgxM2UyYmI1ZTUzMTQ2YWQ4Mjk3OTk1YTY0M2M3OWUyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzI4MjMzZGFmYmQyZjRkMDliMzY5YmJiZjdkMzBjMWE0LmJpbmRQb3B1cChwb3B1cF8xODE2MmYzMWJmM2E0NjQyOWYwY2QxOWNjODFkMjdlMSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNTQyZDY2MDc1NTg0OGU5ODMyODdkZGI1ZTdmNDQzYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTU3NywtNzkuNDQ1MDcyNTk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTI0OTczZDMwYTI0NGNmMjhkZWZhZGFhNWE4MzA1MWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTY0ZmViY2YwYjMwNDIzNzk2ZWE0NDdmNGFiZTBlMTEgPSAkKCc8ZGl2IGlkPSJodG1sX2U2NGZlYmNmMGIzMDQyMzc5NmVhNDQ3ZjRhYmUwZTExIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HbGVuY2Fpcm4sIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2EyNDk3M2QzMGEyNDRjZjI4ZGVmYWRhYTVhODMwNTFjLnNldENvbnRlbnQoaHRtbF9lNjRmZWJjZjBiMzA0MjM3OTZlYTQ0N2Y0YWJlMGUxMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9hNTQyZDY2MDc1NTg0OGU5ODMyODdkZGI1ZTdmNDQzYy5iaW5kUG9wdXAocG9wdXBfYTI0OTczZDMwYTI0NGNmMjhkZWZhZGFhNWE4MzA1MWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTgxYTQ2ZTljY2ZiNDAyMWJmZTg1N2NlMDY4MWRiMjIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTM3ODEzLC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iZDg5NjA1Yjk3NTg0YmUyYWY5YWYxYTE4YmQ5YTYwMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNTA1M2QyYjAzYzU0YzQ4YjhlZGI1NTc5ZmEzY2U1MiA9ICQoJzxkaXYgaWQ9Imh0bWxfZjUwNTNkMmIwM2M1NGM0OGI4ZWRiNTU3OWZhM2NlNTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWV3b29kLUNlZGFydmFsZSwgWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYmQ4OTYwNWI5NzU4NGJlMmFmOWFmMWExOGJkOWE2MDAuc2V0Q29udGVudChodG1sX2Y1MDUzZDJiMDNjNTRjNDhiOGVkYjU1NzlmYTNjZTUyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2U4MWE0NmU5Y2NmYjQwMjFiZmU4NTdjZTA2ODFkYjIyLmJpbmRQb3B1cChwb3B1cF9iZDg5NjA1Yjk3NTg0YmUyYWY5YWYxYTE4YmQ5YTYwMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lZDI4ODk4NmFmZDM0NWIzOWMzZDIzNDhkZDcwZjM1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTAyNTYsLTc5LjQ1MzUxMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83YmZjOTc5MTY1Y2U0NmI4Yjk0MTM0NGU2YjQ3Y2Y3MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85OGRkYzc3Yjk1OWY0MDEyODliNjllMGE3NWRjNzFiMiA9ICQoJzxkaXYgaWQ9Imh0bWxfOThkZGM3N2I5NTlmNDAxMjg5YjY5ZTBhNzVkYzcxYjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhbGVkb25pYS1GYWlyYmFua3MsIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzdiZmM5NzkxNjVjZTQ2YjhiOTQxMzQ0ZTZiNDdjZjczLnNldENvbnRlbnQoaHRtbF85OGRkYzc3Yjk1OWY0MDEyODliNjllMGE3NWRjNzFiMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lZDI4ODk4NmFmZDM0NWIzOWMzZDIzNDhkZDcwZjM1Ni5iaW5kUG9wdXAocG9wdXBfN2JmYzk3OTE2NWNlNDZiOGI5NDEzNDRlNmI0N2NmNzMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNGYxN2MxM2Q5YjBhNDI3OWFjZWU2MmQ4MTExYjljYjQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42Njk1NDIsLTc5LjQyMjU2MzddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDVhZWM0Y2IyNzAyNGIyNmFjZmUxMjJkY2I2MTZkYzkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjI0YWYyNTFlZTVmNDlhNjg3ZGM5NGQ2OTQ2NzA1M2IgPSAkKCc8ZGl2IGlkPSJodG1sX2YyNGFmMjUxZWU1ZjQ5YTY4N2RjOTRkNjk0NjcwNTNiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaHJpc3RpZSwgRG93bnRvd24gVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDVhZWM0Y2IyNzAyNGIyNmFjZmUxMjJkY2I2MTZkYzkuc2V0Q29udGVudChodG1sX2YyNGFmMjUxZWU1ZjQ5YTY4N2RjOTRkNjk0NjcwNTNiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzRmMTdjMTNkOWIwYTQyNzlhY2VlNjJkODExMWI5Y2I0LmJpbmRQb3B1cChwb3B1cF8wNWFlYzRjYjI3MDI0YjI2YWNmZTEyMmRjYjYxNmRjOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83YTVhYjdjZjgxYzU0NTU1ODNlMTM1NjgxZGM4ZTIzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2OTAwNTEwMDAwMDAxLC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzVkZGY2NTY1MTdhMTRkMTQ5MDFjYWRkYTc0MzA0MWY5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg0ZmRhZDYwNzJhZDQ5NTBhM2M2NmY3MTE2NDJkMjQ1ID0gJCgnPGRpdiBpZD0iaHRtbF84NGZkYWQ2MDcyYWQ0OTUwYTNjNjZmNzExNjQyZDI0NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG92ZXJjb3VydCBWaWxsYWdlRHVmZmVyaW4sIFdlc3QgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNWRkZjY1NjUxN2ExNGQxNDkwMWNhZGRhNzQzMDQxZjkuc2V0Q29udGVudChodG1sXzg0ZmRhZDYwNzJhZDQ5NTBhM2M2NmY3MTE2NDJkMjQ1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdhNWFiN2NmODFjNTQ1NTU4M2UxMzU2ODFkYzhlMjM4LmJpbmRQb3B1cChwb3B1cF81ZGRmNjU2NTE3YTE0ZDE0OTAxY2FkZGE3NDMwNDFmOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lNjZkZTg5ZTJjNzE0MmJjOTA4ODk1MDE1ZDJmOGY4YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzkyNjcwMDAwMDAwNiwtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kMzFkMWY5NDMwZjY0YzUyYWFkZWIyZjE4OTlhNGViMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xMzkxYzVjMWE2OTU0YTQ2YjJmNDZhNmY3NmViOGQ4YyA9ICQoJzxkaXYgaWQ9Imh0bWxfMTM5MWM1YzFhNjk1NGE0NmIyZjQ2YTZmNzZlYjhkOGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxpdHRsZSBQb3J0dWdhbFRyaW5pdHksIFdlc3QgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDMxZDFmOTQzMGY2NGM1MmFhZGViMmYxODk5YTRlYjAuc2V0Q29udGVudChodG1sXzEzOTFjNWMxYTY5NTRhNDZiMmY0NmE2Zjc2ZWI4ZDhjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2U2NmRlODllMmM3MTQyYmM5MDg4OTUwMTVkMmY4ZjhhLmJpbmRQb3B1cChwb3B1cF9kMzFkMWY5NDMwZjY0YzUyYWFkZWIyZjE4OTlhNGViMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMmUzNzkyNzcxMDg0M2I1YjM3YWZmNGYzNDRhMDVhMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjg0NzIsLTc5LjQyODE5MTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M1ZWFlYzQ2Y2M2MjQ3Yzg4ZDM3MDA1NTVjNDc0ZmNlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk0N2QzNmE2YzA2YzRhZDI5MWRhOGNmMmNiOTFkNGM1ID0gJCgnPGRpdiBpZD0iaHRtbF85NDdkMzZhNmMwNmM0YWQyOTFkYThjZjJjYjkxZDRjNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnJvY2t0b25FeGhpYml0aW9uIFBsYWNlUGFya2RhbGUgVmlsbGFnZSwgV2VzdCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jNWVhZWM0NmNjNjI0N2M4OGQzNzAwNTU1YzQ3NGZjZS5zZXRDb250ZW50KGh0bWxfOTQ3ZDM2YTZjMDZjNGFkMjkxZGE4Y2YyY2I5MWQ0YzUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZTJlMzc5Mjc3MTA4NDNiNWIzN2FmZjRmMzQ0YTA1YTEuYmluZFBvcHVwKHBvcHVwX2M1ZWFlYzQ2Y2M2MjQ3Yzg4ZDM3MDA1NTVjNDc0ZmNlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzJmMmQ1Yzg0YzU4ODQ4NDQ4MGM1ODc1ODFjNmExNjY3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzEzNzU2MjAwMDAwMDA2LC03OS40OTAwNzM4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzEyMDA1N2FiODBhYjQ2ZWM5YTZlYTNlODVlMmFjNzNiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUyYjM0MDJkZWU4YTQ4YTZhYTQ0YmRjYWIzYmJmOThhID0gJCgnPGRpdiBpZD0iaHRtbF81MmIzNDAyZGVlOGE0OGE2YWE0NGJkY2FiM2JiZjk4YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TWFwbGUgTGVhZiBQYXJrTm9ydGggUGFya1Vwd29vZCBQYXJrLCBOb3J0aCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xMjAwNTdhYjgwYWI0NmVjOWE2ZWEzZTg1ZTJhYzczYi5zZXRDb250ZW50KGh0bWxfNTJiMzQwMmRlZThhNDhhNmFhNDRiZGNhYjNiYmY5OGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMmYyZDVjODRjNTg4NDg0NDgwYzU4NzU4MWM2YTE2NjcuYmluZFBvcHVwKHBvcHVwXzEyMDA1N2FiODBhYjQ2ZWM5YTZlYTNlODVlMmFjNzNiKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2IwZjlhYzFkOTUxMzQ3MjNhNGVmNzQwM2I4YzE3MzE5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkxMTE1OCwtNzkuNDc2MDEzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzBkNTdiN2ZjZWViNDk5YjlkN2RhODcwZjRjNGY3YzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWNkMjVjNGEwOTBjNDMyOGFmNjkzZTZjZjRiM2JmZjcgPSAkKCc8ZGl2IGlkPSJodG1sX2VjZDI1YzRhMDkwYzQzMjhhZjY5M2U2Y2Y0YjNiZmY3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EZWwgUmF5S2VlbGVzZGFsZU1vdW50IERlbm5pc1NpbHZlcnRob3JuLCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MGQ1N2I3ZmNlZWI0OTliOWQ3ZGE4NzBmNGM0ZjdjMi5zZXRDb250ZW50KGh0bWxfZWNkMjVjNGEwOTBjNDMyOGFmNjkzZTZjZjRiM2JmZjcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjBmOWFjMWQ5NTEzNDcyM2E0ZWY3NDAzYjhjMTczMTkuYmluZFBvcHVwKHBvcHVwXzcwZDU3YjdmY2VlYjQ5OWI5ZDdkYTg3MGY0YzRmN2MyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzRkNzI0NWFkZGQyMjQxZTFiMDI4OGJmNmVkMDI1NWQzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjczMTg1Mjk5OTk5OTksLTc5LjQ4NzI2MTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZkMDY4Y2FjNWRhODQ2MTJhOGUzMmE1OGVhNjZkODE1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzJjYTlhN2ExMjc4NTRlN2RiMzlkMmU3NzI0ODdkNWNhID0gJCgnPGRpdiBpZD0iaHRtbF8yY2E5YTdhMTI3ODU0ZTdkYjM5ZDJlNzcyNDg3ZDVjYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEp1bmN0aW9uIE5vcnRoUnVubnltZWRlLCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82ZDA2OGNhYzVkYTg0NjEyYThlMzJhNThlYTY2ZDgxNS5zZXRDb250ZW50KGh0bWxfMmNhOWE3YTEyNzg1NGU3ZGIzOWQyZTc3MjQ4N2Q1Y2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNGQ3MjQ1YWRkZDIyNDFlMWIwMjg4YmY2ZWQwMjU1ZDMuYmluZFBvcHVwKHBvcHVwXzZkMDY4Y2FjNWRhODQ2MTJhOGUzMmE1OGVhNjZkODE1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I1OGNjMTUwNTNkNTRhMThiYThmMTVkNGM4NTliNWQzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYxNjA4MywtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2U0ODE3NTNjMjNkNDQ2NmE4ZDQ1NzA5ZWVhMTdhODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGMyNDcxM2Q1YjBhNDA3OTgyYTA1YWY3ZmFkZGFlM2QgPSAkKCc8ZGl2IGlkPSJodG1sXzRjMjQ3MTNkNWIwYTQwNzk4MmEwNWFmN2ZhZGRhZTNkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdoIFBhcmtUaGUgSnVuY3Rpb24gU291dGgsIFdlc3QgVG9yb250bzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2U0ODE3NTNjMjNkNDQ2NmE4ZDQ1NzA5ZWVhMTdhODAuc2V0Q29udGVudChodG1sXzRjMjQ3MTNkNWIwYTQwNzk4MmEwNWFmN2ZhZGRhZTNkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I1OGNjMTUwNTNkNTRhMThiYThmMTVkNGM4NTliNWQzLmJpbmRQb3B1cChwb3B1cF83ZTQ4MTc1M2MyM2Q0NDY2YThkNDU3MDllZWExN2E4MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMmJhZTdhY2EyM2I0NThiYWIxY2U2OWUwNTNmMjYxNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODk1OTcsLTc5LjQ1NjMyNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81ODdlODFjNTlhZjE0NDE0YWIxOWY5MzM5M2I3ODYzNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81ZTE3NzUxNjQ1ZDg0MmVjOTFlNTcwN2FkYmUwN2MwNiA9ICQoJzxkaXYgaWQ9Imh0bWxfNWUxNzc1MTY0NWQ4NDJlYzkxZTU3MDdhZGJlMDdjMDYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhcmtkYWxlUm9uY2VzdmFsbGVzLCBXZXN0IFRvcm9udG88L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU4N2U4MWM1OWFmMTQ0MTRhYjE5ZjkzMzkzYjc4NjM0LnNldENvbnRlbnQoaHRtbF81ZTE3NzUxNjQ1ZDg0MmVjOTFlNTcwN2FkYmUwN2MwNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jMmJhZTdhY2EyM2I0NThiYWIxY2U2OWUwNTNmMjYxNS5iaW5kUG9wdXAocG9wdXBfNTg3ZTgxYzU5YWYxNDQxNGFiMTlmOTMzOTNiNzg2MzQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDMyMGE3NzA2YmM1NDFlMGE2M2ZlNTZkMjhlOGYxNzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTE1NzA2LC03OS40ODQ0NDk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzkzODk2NzMwNGJhODQ2ZTJhYWQwYzQ1NDM3Y2NkYTVmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2VlOWJlNDc5MTA3YjRjODZiZGJiZDMxYjgwMWI4ZDE3ID0gJCgnPGRpdiBpZD0iaHRtbF9lZTliZTQ3OTEwN2I0Yzg2YmRiYmQzMWI4MDFiOGQxNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UnVubnltZWRlU3dhbnNlYSwgV2VzdCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85Mzg5NjczMDRiYTg0NmUyYWFkMGM0NTQzN2NjZGE1Zi5zZXRDb250ZW50KGh0bWxfZWU5YmU0NzkxMDdiNGM4NmJkYmJkMzFiODAxYjhkMTcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDMyMGE3NzA2YmM1NDFlMGE2M2ZlNTZkMjhlOGYxNzEuYmluZFBvcHVwKHBvcHVwXzkzODk2NzMwNGJhODQ2ZTJhYWQwYzQ1NDM3Y2NkYTVmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzk3Y2Q3MWM0M2M0NjRjNzM4OGM5ZTlmYWE2NWViYTQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyMzAxNSwtNzkuMzg5NDkzOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iY2Q3MmZmZDdhODk0MmZkYTA2ZmRmYjM1YzU4YzkzNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xMTU4ODFmMjFkZjA0NDI1OWRkNDM5ODE0ZDYwMjc3MiA9ICQoJzxkaXYgaWQ9Imh0bWxfMTE1ODgxZjIxZGYwNDQyNTlkZDQzOTgxNGQ2MDI3NzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlF1ZWVuJiMzOTtzIFBhcmssIFF1ZWVuJiMzOTtzIFBhcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JjZDcyZmZkN2E4OTQyZmRhMDZmZGZiMzVjNThjOTM0LnNldENvbnRlbnQoaHRtbF8xMTU4ODFmMjFkZjA0NDI1OWRkNDM5ODE0ZDYwMjc3Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85N2NkNzFjNDNjNDY0YzczODhjOWU5ZmFhNjVlYmE0OC5iaW5kUG9wdXAocG9wdXBfYmNkNzJmZmQ3YTg5NDJmZGEwNmZkZmIzNWM1OGM5MzQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTlmYjI4MzE0OGMzNDY0Y2I5MjhmZmJlZjJlZThlMTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MzY5NjU2LC03OS42MTU4MTg5OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mYTc1NDE0NjAwNGE0Nzg4YmFiYzUyMTdjZmEwZTk1MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lODdlZGVjNGQzMjg0ZTFmYjJhYzViNWFmNjU3Nzc3ZSA9ICQoJzxkaXYgaWQ9Imh0bWxfZTg3ZWRlYzRkMzI4NGUxZmIyYWM1YjVhZjY1Nzc3N2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhbmFkYSBQb3N0IEdhdGV3YXkgUHJvY2Vzc2luZyBDZW50cmUsIE1pc3Npc3NhdWdhPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mYTc1NDE0NjAwNGE0Nzg4YmFiYzUyMTdjZmEwZTk1MC5zZXRDb250ZW50KGh0bWxfZTg3ZWRlYzRkMzI4NGUxZmIyYWM1YjVhZjY1Nzc3N2UpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNTlmYjI4MzE0OGMzNDY0Y2I5MjhmZmJlZjJlZThlMTQuYmluZFBvcHVwKHBvcHVwX2ZhNzU0MTQ2MDA0YTQ3ODhiYWJjNTIxN2NmYTBlOTUwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RlMTkwMzg0ZGEzMTRlNDM4YmM5NjAzYzUwNTU3Y2U4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjYyNzQzOSwtNzkuMzIxNTU4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzYxYzZlZWYyYTc4YzRlMWE5NzFkMzM4OGZiMTE0YjgwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2JlM2FiNGNiYzdjNjQxMzc4MjZkOWZiNjZhYTBiODdkID0gJCgnPGRpdiBpZD0iaHRtbF9iZTNhYjRjYmM3YzY0MTM3ODI2ZDlmYjY2YWEwYjg3ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgUmVwbHkgTWFpbCBQcm9jZXNzaW5nIENlbnRyZSA5NjkgRWFzdGVybiwgRWFzdCBUb3JvbnRvPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82MWM2ZWVmMmE3OGM0ZTFhOTcxZDMzODhmYjExNGI4MC5zZXRDb250ZW50KGh0bWxfYmUzYWI0Y2JjN2M2NDEzNzgyNmQ5ZmI2NmFhMGI4N2QpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZGUxOTAzODRkYTMxNGU0MzhiYzk2MDNjNTA1NTdjZTguYmluZFBvcHVwKHBvcHVwXzYxYzZlZWYyYTc4YzRlMWE5NzFkMzM4OGZiMTE0YjgwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzUzODU2NmRmYWExNjQ0NDc4ZWFhNGExOGVjZjc4NWE4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjA1NjQ2NiwtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWFhMjk3ZDIzYTJiNDQ3MmJlOTYzNDNlZjI3ZDk4ODYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjkwMmRlYmUxYTdlNGUzYzljMWZiYjc3M2QxOTAzMWIgPSAkKCc8ZGl2IGlkPSJodG1sXzI5MDJkZWJlMWE3ZTRlM2M5YzFmYmI3NzNkMTkwMzFiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1iZXIgQmF5IFNob3Jlc01pbWljbyBTb3V0aE5ldyBUb3JvbnRvLCBFdG9iaWNva2U8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2VhYTI5N2QyM2EyYjQ0NzJiZTk2MzQzZWYyN2Q5ODg2LnNldENvbnRlbnQoaHRtbF8yOTAyZGViZTFhN2U0ZTNjOWMxZmJiNzczZDE5MDMxYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81Mzg1NjZkZmFhMTY0NDQ3OGVhYTRhMThlY2Y3ODVhOC5iaW5kUG9wdXAocG9wdXBfZWFhMjk3ZDIzYTJiNDQ3MmJlOTYzNDNlZjI3ZDk4ODYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfM2MwYmU4ZmU4ZDljNDJkZTllNTljZTQxNjVmODgwMjAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDI0MTM3MDAwMDAwMSwtNzkuNTQzNDg0MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZWZlYWJjZTA4NWUwNDYwOTgyZWI1MDZkZDhkNjIyOWMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzk0NjY1OGE0N2FlNGVmOGE5NzViZWVkOGE3ODg5ZmUgPSAkKCc8ZGl2IGlkPSJodG1sXzc5NDY2NThhNDdhZTRlZjhhOTc1YmVlZDhhNzg4OWZlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BbGRlcndvb2RMb25nIEJyYW5jaCwgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lZmVhYmNlMDg1ZTA0NjA5ODJlYjUwNmRkOGQ2MjI5Yy5zZXRDb250ZW50KGh0bWxfNzk0NjY1OGE0N2FlNGVmOGE5NzViZWVkOGE3ODg5ZmUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2MwYmU4ZmU4ZDljNDJkZTllNTljZTQxNjVmODgwMjAuYmluZFBvcHVwKHBvcHVwX2VmZWFiY2UwODVlMDQ2MDk4MmViNTA2ZGQ4ZDYyMjljKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQwYzhjZWFlN2E0NDQ5ZmY5MTBmM2Y1YTdhODVhOTU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzNjUzNjAwMDAwMDA1LC03OS41MDY5NDM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMyYzNmM2IxMmNkZDQ1NjZhOWY4NzU3MDcyZDVjYzk3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzVhNTk3YzJkMWFkZDQ3YTg5YzMwOTQyYTE3NTU2ZWFjID0gJCgnPGRpdiBpZD0iaHRtbF81YTU5N2MyZDFhZGQ0N2E4OWMzMDk0MmExNzU1NmVhYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEtpbmdzd2F5TW9udGdvbWVyeSBSb2FkT2xkIE1pbGwgTm9ydGgsIEV0b2JpY29rZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzJjM2YzYjEyY2RkNDU2NmE5Zjg3NTcwNzJkNWNjOTcuc2V0Q29udGVudChodG1sXzVhNTk3YzJkMWFkZDQ3YTg5YzMwOTQyYTE3NTU2ZWFjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQwYzhjZWFlN2E0NDQ5ZmY5MTBmM2Y1YTdhODVhOTU1LmJpbmRQb3B1cChwb3B1cF8zMmMzZjNiMTJjZGQ0NTY2YTlmODc1NzA3MmQ1Y2M5Nyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNmUxY2UxMjEyN2U0YWQ5OWMzNjJkM2MyNDBiZDVmYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjI1NzksLTc5LjQ5ODUwOTA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VmZDMyM2YxZmRlNDQ3NDY4MjBiYzQ0ZjUyMDUwYjM4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ0NTMwN2Q2ZGRkNTRiMjFhYjZlNWY5NzVlNDRhOWQwID0gJCgnPGRpdiBpZD0iaHRtbF80NDUzMDdkNmRkZDU0YjIxYWI2ZTVmOTc1ZTQ0YTlkMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIEJheUtpbmcmIzM5O3MgTWlsbCBQYXJrS2luZ3N3YXkgUGFyayBTb3V0aCBFYXN0TWltaWNvIE5FT2xkIE1pbGwgU291dGhUaGUgUXVlZW5zd2F5IEVhc3RSb3lhbCBZb3JrIFNvdXRoIEVhc3RTdW5ueWxlYSwgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lZmQzMjNmMWZkZTQ0NzQ2ODIwYmM0NGY1MjA1MGIzOC5zZXRDb250ZW50KGh0bWxfNDQ1MzA3ZDZkZGQ1NGIyMWFiNmU1Zjk3NWU0NGE5ZDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZjZlMWNlMTIxMjdlNGFkOTljMzYyZDNjMjQwYmQ1ZmEuYmluZFBvcHVwKHBvcHVwX2VmZDMyM2YxZmRlNDQ3NDY4MjBiYzQ0ZjUyMDUwYjM4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ViNzk3MmZjMmE2YTRiNDM4ZjJmNjZiZGJlMjJlMjA3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4ODQwOCwtNzkuNTIwOTk5NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOWVkNzAzNjYwMzE4NGZlYmIzNjU2MTQ4NjIwMDYwMzQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjUxN2UwYjg0YmE5NDZlYWFjOWEwMmNlM2NiZjk0MzMgPSAkKCc8ZGl2IGlkPSJodG1sXzI1MTdlMGI4NGJhOTQ2ZWFhYzlhMDJjZTNjYmY5NDMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaW5nc3dheSBQYXJrIFNvdXRoIFdlc3RNaW1pY28gTldUaGUgUXVlZW5zd2F5IFdlc3RSb3lhbCBZb3JrIFNvdXRoIFdlc3RTb3V0aCBvZiBCbG9vciwgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85ZWQ3MDM2NjAzMTg0ZmViYjM2NTYxNDg2MjAwNjAzNC5zZXRDb250ZW50KGh0bWxfMjUxN2UwYjg0YmE5NDZlYWFjOWEwMmNlM2NiZjk0MzMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfZWI3OTcyZmMyYTZhNGI0MzhmMmY2NmJkYmUyMmUyMDcuYmluZFBvcHVwKHBvcHVwXzllZDcwMzY2MDMxODRmZWJiMzY1NjE0ODYyMDA2MDM0KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YyN2NlNDQwODlmNzRjMzk5MTkxY2Y2NDE1MDM1MzM5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY3ODU1NiwtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTE4MTc0OTU1OTY5NDM4M2E0YmU0NjZiOTIxZTA1MjcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2Q5MGQzNzExOTNhNGUwNjllYTI1NzIyYzBkY2I0NmQgPSAkKCc8ZGl2IGlkPSJodG1sX2NkOTBkMzcxMTkzYTRlMDY5ZWEyNTcyMmMwZGNiNDZkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Jc2xpbmd0b24gQXZlbnVlLCBFdG9iaWNva2U8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzUxODE3NDk1NTk2OTQzODNhNGJlNDY2YjkyMWUwNTI3LnNldENvbnRlbnQoaHRtbF9jZDkwZDM3MTE5M2E0ZTA2OWVhMjU3MjJjMGRjYjQ2ZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mMjdjZTQ0MDg5Zjc0YzM5OTE5MWNmNjQxNTAzNTMzOS5iaW5kUG9wdXAocG9wdXBfNTE4MTc0OTU1OTY5NDM4M2E0YmU0NjZiOTIxZTA1MjcpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWRiNGM5NGI0YWI3NDZjZjg1OWI3ZjM0Nzg0MzcxNzUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTA5NDMyLC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNDc3YjJkNDFjNzc0MDc5YTY0YmJmOTJiYWQ2YTZhMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZjUzN2UzNzI5YjE0MmUyYTkzOGRiZTI1ODU1MDljYyA9ICQoJzxkaXYgaWQ9Imh0bWxfZGY1MzdlMzcyOWIxNDJlMmE5MzhkYmUyNTg1NTA5Y2MiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsb3ZlcmRhbGVJc2xpbmd0b25NYXJ0aW4gR3JvdmVQcmluY2VzcyBHYXJkZW5zV2VzdCBEZWFuZSBQYXJrLCBFdG9iaWNva2U8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M0NzdiMmQ0MWM3NzQwNzlhNjRiYmY5MmJhZDZhNmEyLnNldENvbnRlbnQoaHRtbF9kZjUzN2UzNzI5YjE0MmUyYTkzOGRiZTI1ODU1MDljYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lZGI0Yzk0YjRhYjc0NmNmODU5YjdmMzQ3ODQzNzE3NS5iaW5kUG9wdXAocG9wdXBfYzQ3N2IyZDQxYzc3NDA3OWE2NGJiZjkyYmFkNmE2YTIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWUyNGIwZjRkMjU1NDNlZDlkZmEwZjQzZjQ5Y2VhNmMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDM1MTUyLC03OS41NzcyMDA3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kN2YyOWFlOTJmMzc0MDlkOGY4M2FmMzFlNGNmZjJkNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xYjU4MDVmOWM3YTM0OTBhYjc3OTdiZWY1OWQyMmE3MCA9ICQoJzxkaXYgaWQ9Imh0bWxfMWI1ODA1ZjljN2EzNDkwYWI3Nzk3YmVmNTlkMjJhNzAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJsb29yZGFsZSBHYXJkZW5zRXJpbmdhdGVNYXJrbGFuZCBXb29kT2xkIEJ1cm5oYW10aG9ycGUsIEV0b2JpY29rZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDdmMjlhZTkyZjM3NDA5ZDhmODNhZjMxZTRjZmYyZDYuc2V0Q29udGVudChodG1sXzFiNTgwNWY5YzdhMzQ5MGFiNzc5N2JlZjU5ZDIyYTcwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzllMjRiMGY0ZDI1NTQzZWQ5ZGZhMGY0M2Y0OWNlYTZjLmJpbmRQb3B1cChwb3B1cF9kN2YyOWFlOTJmMzc0MDlkOGY4M2FmMzFlNGNmZjJkNik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mMWFjMDI0MzUxZDU0ZDVhYWI2MDg1MDM5Njc5OWI4MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NjMwMzMsLTc5LjU2NTk2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2NmYzllOWYzNWEyZjQ5ZTQ5YjMxNjM4YjA4MmVhODMzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBmNWFiZDQ4ZmE3YzQ1ZjBhMDNmYmNiMjgxOTQ3MjE4ID0gJCgnPGRpdiBpZD0iaHRtbF8wZjVhYmQ0OGZhN2M0NWYwYTAzZmJjYjI4MTk0NzIxOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVyIFN1bW1pdCwgTm9ydGggWW9yazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2ZjOWU5ZjM1YTJmNDllNDliMzE2MzhiMDgyZWE4MzMuc2V0Q29udGVudChodG1sXzBmNWFiZDQ4ZmE3YzQ1ZjBhMDNmYmNiMjgxOTQ3MjE4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YxYWMwMjQzNTFkNTRkNWFhYjYwODUwMzk2Nzk5YjgzLmJpbmRQb3B1cChwb3B1cF9jZmM5ZTlmMzVhMmY0OWU0OWIzMTYzOGIwODJlYTgzMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83MmUyMzYyMWJhYWI0MWRmODdmYjEzYTZiZjE5N2MwMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcyNDc2NTksLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzAyZTRiYzcwYWVlZTRmYzlhMGNjMGMzMGE1NzViMTdmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E1ZjU2ZjVhMjFjMjRjYmY4MzExOGQyZjFhMjcyNjNlID0gJCgnPGRpdiBpZD0iaHRtbF9hNWY1NmY1YTIxYzI0Y2JmODMxMThkMmYxYTI3MjYzZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RW1lcnlIdW1iZXJsZWEsIE5vcnRoIFlvcms8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzAyZTRiYzcwYWVlZTRmYzlhMGNjMGMzMGE1NzViMTdmLnNldENvbnRlbnQoaHRtbF9hNWY1NmY1YTIxYzI0Y2JmODMxMThkMmYxYTI3MjYzZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl83MmUyMzYyMWJhYWI0MWRmODdmYjEzYTZiZjE5N2MwMS5iaW5kUG9wdXAocG9wdXBfMDJlNGJjNzBhZWVlNGZjOWEwY2MwYzMwYTU3NWIxN2YpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjkzNDgzMWIxNmRiNGQ3NjllY2IwM2RmNjhhZDZmMWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsLTc5LjUxODE4ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Q1MjBmMzA0Nzg0NDQzYjhiZDMyZDZjMGZjOGZhYzU1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNlZmM4NGNmNTkwYzQwYmI4MTY0YWI1Yzk5ODc5OGI3ID0gJCgnPGRpdiBpZD0iaHRtbF8zZWZjODRjZjU5MGM0MGJiODE2NGFiNWM5OTg3OThiNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdG9uLCBZb3JrPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kNTIwZjMwNDc4NDQ0M2I4YmQzMmQ2YzBmYzhmYWM1NS5zZXRDb250ZW50KGh0bWxfM2VmYzg0Y2Y1OTBjNDBiYjgxNjRhYjVjOTk4Nzk4YjcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjkzNDgzMWIxNmRiNGQ3NjllY2IwM2RmNjhhZDZmMWMuYmluZFBvcHVwKHBvcHVwX2Q1MjBmMzA0Nzg0NDQzYjhiZDMyZDZjMGZjOGZhYzU1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA1OTg3MWY4ODE1MzQ3YzZhZTg3OTFjNWUwMDU5MTI3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2MzE5LC03OS41MzIyNDI0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MzBiYWJmYzcxNDI0YzJkYjczMWFlZjM4YzMzYTBkNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83YWY5NjU5ZjQ1NzE0YzM1YTRhY2RlZTE4NzA4MmY1ZiA9ICQoJzxkaXYgaWQ9Imh0bWxfN2FmOTY1OWY0NTcxNGMzNWE0YWNkZWUxODcwODJmNWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3Rtb3VudCwgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MzBiYWJmYzcxNDI0YzJkYjczMWFlZjM4YzMzYTBkNi5zZXRDb250ZW50KGh0bWxfN2FmOTY1OWY0NTcxNGMzNWE0YWNkZWUxODcwODJmNWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDU5ODcxZjg4MTUzNDdjNmFlODc5MWM1ZTAwNTkxMjcuYmluZFBvcHVwKHBvcHVwXzczMGJhYmZjNzE0MjRjMmRiNzMxYWVmMzhjMzNhMGQ2KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzcyOWQ4NmM1YjFhNDQyMWU4ZWFhNWVkODI4MzdjZmE4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg4OTA1NCwtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfZjE0YmI3ZjZlMTEwNDg5MTg1Y2I1ZmVmY2M0MTEwMGMpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2M4Y2ZjZmQxNjY2NDNiYzg5NzNmODAxYmYxYTVjZDMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTQwYWM3OTJjMjMyNDA2M2FmZWFlM2UxYTMxMDEzNTggPSAkKCc8ZGl2IGlkPSJodG1sX2U0MGFjNzkyYzIzMjQwNjNhZmVhZTNlMWEzMTAxMzU4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaW5nc3ZpZXcgVmlsbGFnZU1hcnRpbiBHcm92ZSBHYXJkZW5zUmljaHZpZXcgR2FyZGVuc1N0LiBQaGlsbGlwcywgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zYzhjZmNmZDE2NjY0M2JjODk3M2Y4MDFiZjFhNWNkMy5zZXRDb250ZW50KGh0bWxfZTQwYWM3OTJjMjMyNDA2M2FmZWFlM2UxYTMxMDEzNTgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNzI5ZDg2YzViMWE0NDIxZThlYWE1ZWQ4MjgzN2NmYTguYmluZFBvcHVwKHBvcHVwXzNjOGNmY2ZkMTY2NjQzYmM4OTczZjgwMWJmMWE1Y2QzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZlZGRlNWViMGM2MDQ1NDVhZGZhYzNmZjEyZGNiYmU4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5NDE2Mzk5OTk5OTk2LC03OS41ODg0MzY5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2YxNGJiN2Y2ZTExMDQ4OTE4NWNiNWZlZmNjNDExMDBjKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2JkYzg4MjNiNDkyYjQwOWJiNmNiYjI4ZDQ5OGM1YzMzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZlOWQzY2M3N2EwZTQ2Y2RhZWM1NzkyZDY5ZjBkZjBjID0gJCgnPGRpdiBpZD0iaHRtbF82ZTlkM2NjNzdhMGU0NmNkYWVjNTc5MmQ2OWYwZGYwYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWxiaW9uIEdhcmRlbnNCZWF1bW9uZCBIZWlnaHRzSHVtYmVyZ2F0ZUphbWVzdG93bk1vdW50IE9saXZlU2lsdmVyc3RvbmVTb3V0aCBTdGVlbGVzVGhpc3RsZXRvd24sIEV0b2JpY29rZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYmRjODgyM2I0OTJiNDA5YmI2Y2JiMjhkNDk4YzVjMzMuc2V0Q29udGVudChodG1sXzZlOWQzY2M3N2EwZTQ2Y2RhZWM1NzkyZDY5ZjBkZjBjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2ZlZGRlNWViMGM2MDQ1NDVhZGZhYzNmZjEyZGNiYmU4LmJpbmRQb3B1cChwb3B1cF9iZGM4ODIzYjQ5MmI0MDliYjZjYmIyOGQ0OThjNWMzMyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wNDM1YmNlYjI1OTA0NjhjYmQ3NTU2ZDczZmMyYjU3ZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNjc0ODI5OTk5OTk5NCwtNzkuNTk0MDU0NF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9mMTRiYjdmNmUxMTA0ODkxODVjYjVmZWZjYzQxMTAwYyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mNDM5ZGYzMjZhMmI0NDIwODI1MDZhZmZmNDJjODk0YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yNTE5MzQxYzVlNTg0ZDQzYTVkZWU5Y2U1MDBjOTQ5MSA9ICQoJzxkaXYgaWQ9Imh0bWxfMjUxOTM0MWM1ZTU4NGQ0M2E1ZGVlOWNlNTAwYzk0OTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRod2VzdCwgRXRvYmljb2tlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mNDM5ZGYzMjZhMmI0NDIwODI1MDZhZmZmNDJjODk0Yy5zZXRDb250ZW50KGh0bWxfMjUxOTM0MWM1ZTU4NGQ0M2E1ZGVlOWNlNTAwYzk0OTEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDQzNWJjZWIyNTkwNDY4Y2JkNzU1NmQ3M2ZjMmI1N2YuYmluZFBvcHVwKHBvcHVwX2Y0MzlkZjMyNmEyYjQ0MjA4MjUwNmFmZmY0MmM4OTRjKTsKCiAgICAgICAgICAgIAogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7fd989f86b00>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_Toronto = folium.Map(location=[latitude, longitude], zoom_start=10)\n",
"# add markers to map\n",
"for lat, lng, borough, neighborhood in zip(dfs3['Latitude'], dfs3['Longitude'], dfs3['Borough'], dfs3['Neighbourhood']):\n",
" label = '{}, {}'.format(neighborhood, borough)\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).add_to(map_Toronto) \n",
"map_Toronto"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Scarborough will be used for the analyses"
]
},
{
"cell_type": "code",
"execution_count": 17,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood Latitude \\\n",
"0 M1B Scarborough RougeMalvern 43.806686 \n",
"1 M1C Scarborough Highland CreekRouge HillPort Union 43.784535 \n",
"2 M1E Scarborough GuildwoodMorningsideWest Hill 43.763573 \n",
"3 M1G Scarborough Woburn 43.770992 \n",
"4 M1H Scarborough Cedarbrae 43.773136 \n",
"\n",
" Longitude \n",
"0 -79.194353 \n",
"1 -79.160497 \n",
"2 -79.188711 \n",
"3 -79.216917 \n",
"4 -79.239476 "
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_data = dfs3[dfs3['Borough'] == 'Scarborough'].reset_index(drop=True)\n",
"Scarborough_data.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Get the coordinates of 'Scarborough'"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The geograpical coordinate of Scarborough are 43.773077, -79.257774.\n"
]
}
],
"source": [
"address = 'Scarborough, CA'\n",
"geolocator = Nominatim()\n",
"location = geolocator.geocode(address)\n",
"latitude = location.latitude\n",
"longitude = location.longitude\n",
"print('The geograpical coordinate of Scarborough are {}, {}.'.format(latitude, longitude))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create the map of 'Scarborough' using latitude and longitude values"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5MiA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5MicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDMuNzczMDc3LC03OS4yNTc3NzRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyXzU0NDRlNjJhNWY3OTRlNDY4N2QzNzJmYmMwZjlmNTFlID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xYmQ4NzkxNGQzNDA0ZDcwOTAyNjJlYzhjOGRlYjQ4MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwNjY4NjI5OTk5OTk5NiwtNzkuMTk0MzUzNDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmFjZTViYjcxNWY5NDM4NzhkOTZkMjQ2NDg4M2U5ZDYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOTExOGUyMTJmNDkwNDM4MTg3Y2IyYWZiYWQwYzBlZmEgPSAkKCc8ZGl2IGlkPSJodG1sXzkxMThlMjEyZjQ5MDQzODE4N2NiMmFmYmFkMGMwZWZhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZU1hbHZlcm48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZhY2U1YmI3MTVmOTQzODc4ZDk2ZDI0NjQ4ODNlOWQ2LnNldENvbnRlbnQoaHRtbF85MTE4ZTIxMmY0OTA0MzgxODdjYjJhZmJhZDBjMGVmYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xYmQ4NzkxNGQzNDA0ZDcwOTAyNjJlYzhjOGRlYjQ4Mi5iaW5kUG9wdXAocG9wdXBfNmFjZTViYjcxNWY5NDM4NzhkOTZkMjQ2NDg4M2U5ZDYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWM2ZGU0ZjdiYTUwNDU0Zjg4YmEwY2U3N2NhNjg1MmMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODQ1MzUxLC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84OGIxNjBmZGNiNjE0M2E2YTk2OGI2NGNkYjYyYjBiZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kN2UxNGFkODA3NmE0ZTc2YTI0OWY5NTY4MGRlY2YxZiA9ICQoJzxkaXYgaWQ9Imh0bWxfZDdlMTRhZDgwNzZhNGU3NmEyNDlmOTU2ODBkZWNmMWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpZ2hsYW5kIENyZWVrUm91Z2UgSGlsbFBvcnQgVW5pb248L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzg4YjE2MGZkY2I2MTQzYTZhOTY4YjY0Y2RiNjJiMGJlLnNldENvbnRlbnQoaHRtbF9kN2UxNGFkODA3NmE0ZTc2YTI0OWY5NTY4MGRlY2YxZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81YzZkZTRmN2JhNTA0NTRmODhiYTBjZTc3Y2E2ODUyYy5iaW5kUG9wdXAocG9wdXBfODhiMTYwZmRjYjYxNDNhNmE5NjhiNjRjZGI2MmIwYmUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZTk0MDc5YTE0MWFhNGRhZWI3YTZkZGExNGVlNzg4OGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NjM1NzI2LC03OS4xODg3MTE1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjNzc3MTI5YjgxYzQwMzhiOGM0YzhiZjIxYTE1MGE2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZmMGIzMjUxODNhMDQzM2ZhMjUzMjA0ZjczNTU5NGZjID0gJCgnPGRpdiBpZD0iaHRtbF82ZjBiMzI1MTgzYTA0MzNmYTI1MzIwNGY3MzU1OTRmYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3VpbGR3b29kTW9ybmluZ3NpZGVXZXN0IEhpbGw8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZjNzc3MTI5YjgxYzQwMzhiOGM0YzhiZjIxYTE1MGE2LnNldENvbnRlbnQoaHRtbF82ZjBiMzI1MTgzYTA0MzNmYTI1MzIwNGY3MzU1OTRmYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lOTQwNzlhMTQxYWE0ZGFlYjdhNmRkYTE0ZWU3ODg4ZC5iaW5kUG9wdXAocG9wdXBfZmM3NzcxMjliODFjNDAzOGI4YzRjOGJmMjFhMTUwYTYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDA5ZmIzOWFkYTA1NGFlN2ExN2U4MDAyMzcwNTcyMzcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzA5OTIxLC03OS4yMTY5MTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mOTBhNjRmZWExNmI0OTNmYjg1ODdmZTU2MDIyOThkYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lYjBlMjYxNjQ2Njg0NTg3ODVmNDJlNzMxNDI2MjZkZiA9ICQoJzxkaXYgaWQ9Imh0bWxfZWIwZTI2MTY0NjY4NDU4Nzg1ZjQyZTczMTQyNjI2ZGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldvYnVybjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjkwYTY0ZmVhMTZiNDkzZmI4NTg3ZmU1NjAyMjk4ZGMuc2V0Q29udGVudChodG1sX2ViMGUyNjE2NDY2ODQ1ODc4NWY0MmU3MzE0MjYyNmRmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2QwOWZiMzlhZGEwNTRhZTdhMTdlODAwMjM3MDU3MjM3LmJpbmRQb3B1cChwb3B1cF9mOTBhNjRmZWExNmI0OTNmYjg1ODdmZTU2MDIyOThkYyk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xMTIxNWM3ZWUxNWI0OGVmYmIwODhkYTU5MjEzMTJmZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MzEzNiwtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZmJhMWY0MTFjZDE4NDlkYWE3MjYwNTc0YWE1YzczOTggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzY5OWM3YzMwNmY3NDMxOWJlNTBlMjZiMjY4NmFlMGMgPSAkKCc8ZGl2IGlkPSJodG1sXzM2OTljN2MzMDZmNzQzMTliZTUwZTI2YjI2ODZhZTBjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZWRhcmJyYWU8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZiYTFmNDExY2QxODQ5ZGFhNzI2MDU3NGFhNWM3Mzk4LnNldENvbnRlbnQoaHRtbF8zNjk5YzdjMzA2Zjc0MzE5YmU1MGUyNmIyNjg2YWUwYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xMTIxNWM3ZWUxNWI0OGVmYmIwODhkYTU5MjEzMTJmZC5iaW5kUG9wdXAocG9wdXBfZmJhMWY0MTFjZDE4NDlkYWE3MjYwNTc0YWE1YzczOTgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmQ5ZjE3MjBmMmNkNGQ0ZThiNjY0NDEwNjAyZjFjODAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NDQ3MzQyLC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83OGYwZTIzZTU5YjQ0MjJjYTE1MTdhODkyMGQ2OTJmZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83ZGVmNDFlYjRhNTc0YjM2ODY0MDQ1ZDJjMzNiMzhiZSA9ICQoJzxkaXYgaWQ9Imh0bWxfN2RlZjQxZWI0YTU3NGIzNjg2NDA0NWQyYzMzYjM4YmUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlNjYXJib3JvdWdoIFZpbGxhZ2U8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc4ZjBlMjNlNTliNDQyMmNhMTUxN2E4OTIwZDY5MmZmLnNldENvbnRlbnQoaHRtbF83ZGVmNDFlYjRhNTc0YjM2ODY0MDQ1ZDJjMzNiMzhiZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iZDlmMTcyMGYyY2Q0ZDRlOGI2NjQ0MTA2MDJmMWM4MC5iaW5kUG9wdXAocG9wdXBfNzhmMGUyM2U1OWI0NDIyY2ExNTE3YTg5MjBkNjkyZmYpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDU0ZDBjMjAwMTE1NGQ0NTk1MDA2M2JmZDZlMjY4MzIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jMTMzYTE3Yjc4NTQ0ZGYxOTcxNDI0ZWE2YTVlNDVhYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yM2YyNTljNGUyNDI0OTQzOTU1ZjA3OTZhM2IyY2JiNCA9ICQoJzxkaXYgaWQ9Imh0bWxfMjNmMjU5YzRlMjQyNDk0Mzk1NWYwNzk2YTNiMmNiYjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgQmlyY2htb3VudCBQYXJrSW9udmlld0tlbm5lZHkgUGFyazwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzEzM2ExN2I3ODU0NGRmMTk3MTQyNGVhNmE1ZTQ1YWEuc2V0Q29udGVudChodG1sXzIzZjI1OWM0ZTI0MjQ5NDM5NTVmMDc5NmEzYjJjYmI0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzA1NGQwYzIwMDExNTRkNDU5NTAwNjNiZmQ2ZTI2ODMyLmJpbmRQb3B1cChwb3B1cF9jMTMzYTE3Yjc4NTQ0ZGYxOTcxNDI0ZWE2YTVlNDVhYSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mMWY2YTk3YzgxMDQ0NTgxOGUwMmEyNDVhN2E1YjkyMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMTExMTcwMDAwMDAwNCwtNzkuMjg0NTc3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMGNkODRiN2RkNDY0MDdiYjA3ZWMwNWEzMTNiN2Q3NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMWM0MjQzMGI3ZDI0NjMyYmRlZTNjMzM1Yjc1ZTQ5YiA9ICQoJzxkaXYgaWQ9Imh0bWxfZDFjNDI0MzBiN2QyNDYzMmJkZWUzYzMzNWI3NWU0OWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsYWlybGVhR29sZGVuIE1pbGVPYWtyaWRnZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTBjZDg0YjdkZDQ2NDA3YmIwN2VjMDVhMzEzYjdkNzUuc2V0Q29udGVudChodG1sX2QxYzQyNDMwYjdkMjQ2MzJiZGVlM2MzMzViNzVlNDliKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YxZjZhOTdjODEwNDQ1ODE4ZTAyYTI0NWE3YTViOTIzLmJpbmRQb3B1cChwb3B1cF9hMGNkODRiN2RkNDY0MDdiYjA3ZWMwNWEzMTNiN2Q3NSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jMzQ4OGVjNDU4MzA0MjczOTIxZTY0YTdmOGU3NGVmYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNjMxNiwtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2NjZDZlOWE5YThjNDg2ODlmODZiOGYxNWU3MjcyNWEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGZhOGNhZDUwMDQzNDBlZmE2Y2YwMGZmNjEyMTY1YzAgPSAkKCc8ZGl2IGlkPSJodG1sX2RmYThjYWQ1MDA0MzQwZWZhNmNmMDBmZjYxMjE2NWMwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGlmZmNyZXN0Q2xpZmZzaWRlU2NhcmJvcm91Z2ggVmlsbGFnZSBXZXN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zY2NkNmU5YTlhOGM0ODY4OWY4NmI4ZjE1ZTcyNzI1YS5zZXRDb250ZW50KGh0bWxfZGZhOGNhZDUwMDQzNDBlZmE2Y2YwMGZmNjEyMTY1YzApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYzM0ODhlYzQ1ODMwNDI3MzkyMWU2NGE3ZjhlNzRlZmIuYmluZFBvcHVwKHBvcHVwXzNjY2Q2ZTlhOWE4YzQ4Njg5Zjg2YjhmMTVlNzI3MjVhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UwNjYzMDcxNmEzMTQzYmY4Y2VmMzIyMTNlYjMzMjE1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkyNjU3MDAwMDAwMDA0LC03OS4yNjQ4NDgxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdlNDAxYmUwMGI4ZjQ1MjA5N2Q3MTY2Y2U2YTg4MWRiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk0NGNiYmIzMTA0YjQyYzM5NjY3YjUxOTdjOGUzYjNiID0gJCgnPGRpdiBpZD0iaHRtbF85NDRjYmJiMzEwNGI0MmMzOTY2N2I1MTk3YzhlM2IzYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmlyY2ggQ2xpZmZDbGlmZnNpZGUgV2VzdDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2U0MDFiZTAwYjhmNDUyMDk3ZDcxNjZjZTZhODgxZGIuc2V0Q29udGVudChodG1sXzk0NGNiYmIzMTA0YjQyYzM5NjY3YjUxOTdjOGUzYjNiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2UwNjYzMDcxNmEzMTQzYmY4Y2VmMzIyMTNlYjMzMjE1LmJpbmRQb3B1cChwb3B1cF83ZTQwMWJlMDBiOGY0NTIwOTdkNzE2NmNlNmE4ODFkYik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80ODQxMzk3ZDVlY2Y0M2MyOGE2MDk2M2QyZmRmMmMwYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NzQwOTYsLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2NmNTlhZmI5OWRmNjRhZWViYWNkODcyZDQ4MjJjYWZmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzA2ODc3N2ZkZmE2MjQ5MDJhMzhiNGRkZDM3Njc2ZGIwID0gJCgnPGRpdiBpZD0iaHRtbF8wNjg3NzdmZGZhNjI0OTAyYTM4YjRkZGQzNzY3NmRiMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG9yc2V0IFBhcmtTY2FyYm9yb3VnaCBUb3duIENlbnRyZVdleGZvcmQgSGVpZ2h0czwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2Y1OWFmYjk5ZGY2NGFlZWJhY2Q4NzJkNDgyMmNhZmYuc2V0Q29udGVudChodG1sXzA2ODc3N2ZkZmE2MjQ5MDJhMzhiNGRkZDM3Njc2ZGIwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzQ4NDEzOTdkNWVjZjQzYzI4YTYwOTYzZDJmZGYyYzBjLmJpbmRQb3B1cChwb3B1cF9jZjU5YWZiOTlkZjY0YWVlYmFjZDg3MmQ0ODIyY2FmZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jYmZjNTI0NWRmN2E0MDg2OTYwN2M5NjljNDZlYWMyNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwtNzkuMjk1ODQ5MV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yNGZkNWY1NDIzMWU0NWI4OGNjNTA2ZmZiYmRkYmY0OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMjQ4YTg2MDIzOWE0YzJjYmI4ZmEwY2RhMzk5ZjhmMyA9ICQoJzxkaXYgaWQ9Imh0bWxfZjI0OGE4NjAyMzlhNGMyY2JiOGZhMGNkYTM5OWY4ZjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1hcnl2YWxlV2V4Zm9yZDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjRmZDVmNTQyMzFlNDViODhjYzUwNmZmYmJkZGJmNDkuc2V0Q29udGVudChodG1sX2YyNDhhODYwMjM5YTRjMmNiYjhmYTBjZGEzOTlmOGYzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2NiZmM1MjQ1ZGY3YTQwODY5NjA3Yzk2OWM0NmVhYzI0LmJpbmRQb3B1cChwb3B1cF8yNGZkNWY1NDIzMWU0NWI4OGNjNTA2ZmZiYmRkYmY0OSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNDc2ZTZkNjg1N2E0MjRmYWFkNDhiOWQzNzk2M2UyNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5NDIwMDMsLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzczY2FjNWViYmRiODQwOTVhNWVkMGIxZjg3OTkyMTkyKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Q4NWNjZjE0NzBmYjQzZWI4ZWQxYjc0MzE5MzUyMDFkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdiOGYwYjcxYjlhZTQwNTk4ZTRlMTk1NTJhMTg0ZGFjID0gJCgnPGRpdiBpZD0iaHRtbF83YjhmMGI3MWI5YWU0MDU5OGU0ZTE5NTUyYTE4NGRhYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kODVjY2YxNDcwZmI0M2ViOGVkMWI3NDMxOTM1MjAxZC5zZXRDb250ZW50KGh0bWxfN2I4ZjBiNzFiOWFlNDA1OThlNGUxOTU1MmExODRkYWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYTQ3NmU2ZDY4NTdhNDI0ZmFhZDQ4YjlkMzc5NjNlMjUuYmluZFBvcHVwKHBvcHVwX2Q4NWNjZjE0NzBmYjQzZWI4ZWQxYjc0MzE5MzUyMDFkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2YwNDBkZTQ2NTA1NzQ2NmY5MjY0YWE4YWNmZDRiN2E0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwtNzkuMzA0MzAyMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mNWNlMDU4Y2VkMWU0N2ZhYWY1MzllNzI1ZDg0YjYxZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMmIxZDcwNGM1ZTk0ZWI4ODBlZThmMWNkM2ZjOGNkZSA9ICQoJzxkaXYgaWQ9Imh0bWxfZjJiMWQ3MDRjNWU5NGViODgwZWU4ZjFjZDNmYzhjZGUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsYXJrcyBDb3JuZXJzU3VsbGl2YW5UYW0gTyYjMzk7U2hhbnRlcjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjVjZTA1OGNlZDFlNDdmYWFmNTM5ZTcyNWQ4NGI2MWUuc2V0Q29udGVudChodG1sX2YyYjFkNzA0YzVlOTRlYjg4MGVlOGYxY2QzZmM4Y2RlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YwNDBkZTQ2NTA1NzQ2NmY5MjY0YWE4YWNmZDRiN2E0LmJpbmRQb3B1cChwb3B1cF9mNWNlMDU4Y2VkMWU0N2ZhYWY1MzllNzI1ZDg0YjYxZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82Y2IzMTkxYzM4NDM0M2E1YWQ1NGJkZGQ1N2I1ODMxNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODBlNjZmNGYxMmQ3NDI1MDkzMjk2ZGIyOTQ2ZWRiMmQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2FhMjAwYWE2ODJlNGE3Yjg3MmUxODg2NjQxNTExZDQgPSAkKCc8ZGl2IGlkPSJodG1sX2NhYTIwMGFhNjgyZTRhN2I4NzJlMTg4NjY0MTUxMWQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BZ2luY291cnQgTm9ydGhMJiMzOTtBbW9yZWF1eCBFYXN0TWlsbGlrZW5TdGVlbGVzIEVhc3Q8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzgwZTY2ZjRmMTJkNzQyNTA5MzI5NmRiMjk0NmVkYjJkLnNldENvbnRlbnQoaHRtbF9jYWEyMDBhYTY4MmU0YTdiODcyZTE4ODY2NDE1MTFkNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl82Y2IzMTkxYzM4NDM0M2E1YWQ1NGJkZGQ1N2I1ODMxNS5iaW5kUG9wdXAocG9wdXBfODBlNjZmNGYxMmQ3NDI1MDkzMjk2ZGIyOTQ2ZWRiMmQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDcxMDJkNzk5Yjc1NDgzNjkwNTM3ZGNiYTE5MGMzYmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTk1MjUyMDAwMDAwMDUsLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfNzNjYWM1ZWJiZGI4NDA5NWE1ZWQwYjFmODc5OTIxOTIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmJjZGQ3MTFmOTI1NGJiZDk1ZjYzMDU0YjFkOGI4NTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTMxODJjYWNhMDgzNDhlZWExODllZjE2ZjUwNTdmZDcgPSAkKCc8ZGl2IGlkPSJodG1sXzUzMTgyY2FjYTA4MzQ4ZWVhMTg5ZWYxNmY1MDU3ZmQ3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MJiMzOTtBbW9yZWF1eCBXZXN0U3RlZWxlcyBXZXN0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iYmNkZDcxMWY5MjU0YmJkOTVmNjMwNTRiMWQ4Yjg1MS5zZXRDb250ZW50KGh0bWxfNTMxODJjYWNhMDgzNDhlZWExODllZjE2ZjUwNTdmZDcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDcxMDJkNzk5Yjc1NDgzNjkwNTM3ZGNiYTE5MGMzYmQuYmluZFBvcHVwKHBvcHVwX2JiY2RkNzExZjkyNTRiYmQ5NWY2MzA1NGIxZDhiODUxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzAyZDA5MzI0MzRlNTQ0MTliMTE0MTlmYTdlNDZjZTg4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODM2MTI0NzAwMDAwMDA2LC03OS4yMDU2MzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF83M2NhYzVlYmJkYjg0MDk1YTVlZDBiMWY4Nzk5MjE5Mik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iZWFlNDMzZmEyYjc0YTU5YWZlOTdiNzQzOTk2MThiNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jMjAzM2NhZmNjY2E0NTA0OTg4MDA4NWQxMTYyMTNiZCA9ICQoJzxkaXYgaWQ9Imh0bWxfYzIwMzNjYWZjY2NhNDUwNDk4ODAwODVkMTE2MjEzYmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlVwcGVyIFJvdWdlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iZWFlNDMzZmEyYjc0YTU5YWZlOTdiNzQzOTk2MThiNS5zZXRDb250ZW50KGh0bWxfYzIwMzNjYWZjY2NhNDUwNDk4ODAwODVkMTE2MjEzYmQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMDJkMDkzMjQzNGU1NDQxOWIxMTQxOWZhN2U0NmNlODguYmluZFBvcHVwKHBvcHVwX2JlYWU0MzNmYTJiNzRhNTlhZmU5N2I3NDM5OTYxOGI1KTsKCiAgICAgICAgICAgIAogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7fd9893fa7b8>"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_Scarborough = folium.Map(location=[latitude, longitude], zoom_start=11)\n",
"# add markers to map\n",
"for lat, lng, label in zip(Scarborough_data['Latitude'], Scarborough_data['Longitude'], Scarborough_data['Neighbourhood']):\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).add_to(map_Scarborough) \n",
"map_Scarborough"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### My foursquare ID"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"My foursquare credentails:\n",
"CLIENT_ID: IZJNDNMGN2UG0QC4VTSCO0X3FIJCUWLEOMDME03AZXXKSFK1\n",
"CLIENT_SECRET:2VRK4XTUNZGWEC5FU3ITX45S3KRWYECKYHE10VK0EJLMJHGJ\n"
]
}
],
"source": [
"CLIENT_ID = 'IZJNDNMGN2UG0QC4VTSCO0X3FIJCUWLEOMDME03AZXXKSFK1' # your Foursquare ID\n",
"CLIENT_SECRET = '2VRK4XTUNZGWEC5FU3ITX45S3KRWYECKYHE10VK0EJLMJHGJ' # your Foursquare Secret\n",
"VERSION = '20180605' # Foursquare API version\n",
"print('My foursquare credentails:')\n",
"print('CLIENT_ID: ' + CLIENT_ID)\n",
"print('CLIENT_SECRET:' + CLIENT_SECRET)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### First Neighbourhood in Scarborough"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'RougeMalvern'"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_data.loc[0, 'Neighbourhood']"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(17, 5)"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_data.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Find the Latitude and longitude values of RougeMalvern"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Latitude and longitude values of RougeMalvern are 43.806686299999996, -79.19435340000001.\n"
]
}
],
"source": [
"neighborhood_latitude = Scarborough_data.loc[0, 'Latitude'] # neighborhood latitude value\n",
"neighborhood_longitude = Scarborough_data.loc[0, 'Longitude'] # neighborhood longitude value\n",
"\n",
"neighborhood_name = Scarborough_data.loc[0, 'Neighbourhood'] # neighborhood name\n",
"\n",
"print('Latitude and longitude values of {} are {}, {}.'.format(neighborhood_name, \n",
" neighborhood_latitude, \n",
" neighborhood_longitude))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Fetch nearby venus using the foursquare API"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'https://api.foursquare.com/v2/venues/explore?&client_id=IZJNDNMGN2UG0QC4VTSCO0X3FIJCUWLEOMDME03AZXXKSFK1&client_secret=2VRK4XTUNZGWEC5FU3ITX45S3KRWYECKYHE10VK0EJLMJHGJ&v=20180605&ll=43.806686299999996,-79.19435340000001&radius=500&limit=100'"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"LIMIT = 100 # limit of number of venues returned by Foursquare API\n",
"radius = 500 # define radius\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",
" neighborhood_latitude, \n",
" neighborhood_longitude, \n",
" radius, \n",
" LIMIT)\n",
"url"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Get the json file from url"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'meta': {'code': 200, 'requestId': '5c5761036a60717aef4cb3ea'},\n",
" 'response': {'warning': {'text': \"There aren't a lot of results near you. Try something more general, reset your filters, or expand the search area.\"},\n",
" 'headerLocation': 'Malvern',\n",
" 'headerFullLocation': 'Malvern, Toronto',\n",
" 'headerLocationGranularity': 'neighborhood',\n",
" 'totalResults': 2,\n",
" 'suggestedBounds': {'ne': {'lat': 43.8111863045, 'lng': -79.18812958073042},\n",
" 'sw': {'lat': 43.80218629549999, 'lng': -79.2005772192696}},\n",
" 'groups': [{'type': 'Recommended Places',\n",
" 'name': 'recommended',\n",
" 'items': [{'reasons': {'count': 0,\n",
" 'items': [{'summary': 'This spot is popular',\n",
" 'type': 'general',\n",
" 'reasonName': 'globalInteractionReason'}]},\n",
" 'venue': {'id': '4bb6b9446edc76b0d771311c',\n",
" 'name': \"Wendy's\",\n",
" 'location': {'crossStreet': 'Morningside & Sheppard',\n",
" 'lat': 43.80744841934756,\n",
" 'lng': -79.19905558052072,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 43.80744841934756,\n",
" 'lng': -79.19905558052072}],\n",
" 'distance': 387,\n",
" 'cc': 'CA',\n",
" 'city': 'Toronto',\n",
" 'state': 'ON',\n",
" 'country': 'Canada',\n",
" 'formattedAddress': ['Toronto ON', 'Canada']},\n",
" 'categories': [{'id': '4bf58dd8d48988d16e941735',\n",
" 'name': 'Fast Food Restaurant',\n",
" 'pluralName': 'Fast Food Restaurants',\n",
" 'shortName': 'Fast Food',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/food/fastfood_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'photos': {'count': 0, 'groups': []}},\n",
" 'referralId': 'e-0-4bb6b9446edc76b0d771311c-0'},\n",
" {'reasons': {'count': 0,\n",
" 'items': [{'summary': 'This spot is popular',\n",
" 'type': 'general',\n",
" 'reasonName': 'globalInteractionReason'}]},\n",
" 'venue': {'id': '5539e7d2498edaf4b02673ca',\n",
" 'name': 'Interprovincial Group',\n",
" 'location': {'address': '1315 Morningside Avenue',\n",
" 'lat': 43.8056297,\n",
" 'lng': -79.2003784,\n",
" 'labeledLatLngs': [{'label': 'display',\n",
" 'lat': 43.8056297,\n",
" 'lng': -79.2003784}],\n",
" 'distance': 498,\n",
" 'postalCode': 'M1B 3C5',\n",
" 'cc': 'CA',\n",
" 'city': 'Scarborough',\n",
" 'state': 'ON',\n",
" 'country': 'Canada',\n",
" 'formattedAddress': ['1315 Morningside Avenue',\n",
" 'Scarborough ON M1B 3C5',\n",
" 'Canada']},\n",
" 'categories': [{'id': '52f2ab2ebcbc57f1066b8b28',\n",
" 'name': 'Print Shop',\n",
" 'pluralName': 'Print Shops',\n",
" 'shortName': 'Print Shop',\n",
" 'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/shops/default_',\n",
" 'suffix': '.png'},\n",
" 'primary': True}],\n",
" 'photos': {'count': 0, 'groups': []}},\n",
" 'referralId': 'e-0-5539e7d2498edaf4b02673ca-1'}]}]}}"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = requests.get(url)\n",
"results = s.json()\n",
"results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Function to get the category's type"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"# function that extracts the category of the venue\n",
"def get_category_type(row):\n",
" try:\n",
" categories_list = row['categories']\n",
" except:\n",
" categories_list = row['venue.categories']\n",
" \n",
" if len(categories_list) == 0:\n",
" return None\n",
" else:\n",
" return categories_list[0]['name']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Check how many venues from the url_json"
]
},
{
"cell_type": "code",
"execution_count": 27,
"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>name</th>\n",
" <th>categories</th>\n",
" <th>lat</th>\n",
" <th>lng</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Wendy's</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>43.807448</td>\n",
" <td>-79.199056</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Interprovincial Group</td>\n",
" <td>Print Shop</td>\n",
" <td>43.805630</td>\n",
" <td>-79.200378</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" name categories lat lng\n",
"0 Wendy's Fast Food Restaurant 43.807448 -79.199056\n",
"1 Interprovincial Group Print Shop 43.805630 -79.200378"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"venues = results['response']['groups'][0]['items'] \n",
"nearby_venues = json_normalize(venues) # flatten JSON\n",
"# filter columns\n",
"filtered_columns = ['venue.name', 'venue.categories', 'venue.location.lat', 'venue.location.lng']\n",
"nearby_venues =nearby_venues.loc[:, filtered_columns]\n",
"# filter the category for each row\n",
"nearby_venues['venue.categories'] = nearby_venues.apply(get_category_type, axis=1)\n",
"# clean columns\n",
"nearby_venues.columns = [col.split(\".\")[-1] for col in nearby_venues.columns]\n",
"nearby_venues.head()"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2 venues were returned by Foursquare.\n"
]
}
],
"source": [
"print('{} venues were returned by Foursquare.'.format(nearby_venues.shape[0]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Prepare a function to find the nearby venues"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"def getNearbyVenues(names, latitudes, longitudes, radius=500):\n",
" \n",
" venues_list=[]\n",
" for name, lat, lng in zip(names, latitudes, longitudes):\n",
" print(name)\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",
" lng, \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",
" venues_list.append([(\n",
" name, \n",
" lat, \n",
" lng, \n",
" v['venue']['name'], \n",
" v['venue']['location']['lat'], \n",
" v['venue']['location']['lng'], \n",
" v['venue']['categories'][0]['name']) for v in results])\n",
"\n",
" nearby_venues = pd.DataFrame([item for venue_list in venues_list for item in venue_list])\n",
" nearby_venues.columns = ['Neighborhood', \n",
" 'Neighborhood Latitude', \n",
" 'Neighborhood Longitude', \n",
" 'Venue', \n",
" 'Venue Latitude', \n",
" 'Venue Longitude', \n",
" 'Venue Category']\n",
" \n",
" return(nearby_venues)"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"RougeMalvern\n",
"Highland CreekRouge HillPort Union\n",
"GuildwoodMorningsideWest Hill\n",
"Woburn\n",
"Cedarbrae\n",
"Scarborough Village\n",
"East Birchmount ParkIonviewKennedy Park\n",
"ClairleaGolden MileOakridge\n",
"CliffcrestCliffsideScarborough Village West\n",
"Birch CliffCliffside West\n",
"Dorset ParkScarborough Town CentreWexford Heights\n",
"MaryvaleWexford\n",
"Agincourt\n",
"Clarks CornersSullivanTam O'Shanter\n",
"Agincourt NorthL'Amoreaux EastMillikenSteeles East\n",
"L'Amoreaux WestSteeles West\n",
"Upper Rouge\n"
]
}
],
"source": [
"Scarborough_venues = getNearbyVenues(names=Scarborough_data['Neighbourhood'],\n",
" latitudes=Scarborough_data['Latitude'],\n",
" longitudes=Scarborough_data['Longitude']\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 31,
"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>Neighborhood Latitude</th>\n",
" <th>Neighborhood Longitude</th>\n",
" <th>Venue</th>\n",
" <th>Venue Latitude</th>\n",
" <th>Venue Longitude</th>\n",
" <th>Venue Category</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Wendy's</td>\n",
" <td>43.807448</td>\n",
" <td>-79.199056</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Interprovincial Group</td>\n",
" <td>43.805630</td>\n",
" <td>-79.200378</td>\n",
" <td>Print Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Royal Canadian Legion</td>\n",
" <td>43.782533</td>\n",
" <td>-79.163085</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Affordable Toronto Movers</td>\n",
" <td>43.787919</td>\n",
" <td>-79.162977</td>\n",
" <td>Moving Target</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Swiss Chalet Rotisserie &amp; Grill</td>\n",
" <td>43.767697</td>\n",
" <td>-79.189914</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>G &amp; G Electronics</td>\n",
" <td>43.765309</td>\n",
" <td>-79.191537</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Marina Spa</td>\n",
" <td>43.766000</td>\n",
" <td>-79.191000</td>\n",
" <td>Spa</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Big Bite Burrito</td>\n",
" <td>43.766299</td>\n",
" <td>-79.190720</td>\n",
" <td>Mexican Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Enterprise Rent-A-Car</td>\n",
" <td>43.764076</td>\n",
" <td>-79.193406</td>\n",
" <td>Rental Car Location</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Woburn Medical Centre</td>\n",
" <td>43.766631</td>\n",
" <td>-79.192286</td>\n",
" <td>Medical Center</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Eggsmart</td>\n",
" <td>43.767800</td>\n",
" <td>-79.190466</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Starbucks</td>\n",
" <td>43.770037</td>\n",
" <td>-79.221156</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.770827</td>\n",
" <td>-79.223078</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Korean Grill House</td>\n",
" <td>43.770812</td>\n",
" <td>-79.214502</td>\n",
" <td>Korean Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Al-Hamd Biryani &amp; Pizza</td>\n",
" <td>43.767585</td>\n",
" <td>-79.219570</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Federick Restaurant</td>\n",
" <td>43.774697</td>\n",
" <td>-79.241142</td>\n",
" <td>Hakka Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Drupati's Roti &amp; Doubles</td>\n",
" <td>43.775222</td>\n",
" <td>-79.241678</td>\n",
" <td>Caribbean Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Thai One On</td>\n",
" <td>43.774468</td>\n",
" <td>-79.241268</td>\n",
" <td>Thai Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Centennial Recreation Centre</td>\n",
" <td>43.774593</td>\n",
" <td>-79.236500</td>\n",
" <td>Athletics &amp; Sports</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>TD Canada Trust</td>\n",
" <td>43.774952</td>\n",
" <td>-79.241343</td>\n",
" <td>Bank</td>\n",
" </tr>\n",
" <tr>\n",
" <th>20</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>B&amp;A Bakery</td>\n",
" <td>43.774391</td>\n",
" <td>-79.243877</td>\n",
" <td>Bakery</td>\n",
" </tr>\n",
" <tr>\n",
" <th>21</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Popeyes Louisiana Kitchen</td>\n",
" <td>43.775930</td>\n",
" <td>-79.235328</td>\n",
" <td>Fried Chicken Joint</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>McCowan Park</td>\n",
" <td>43.745089</td>\n",
" <td>-79.239336</td>\n",
" <td>Playground</td>\n",
" </tr>\n",
" <tr>\n",
" <th>23</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>Tumbe Cafe</td>\n",
" <td>43.744058</td>\n",
" <td>-79.244021</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>24</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>Elane Barbers</td>\n",
" <td>43.743706</td>\n",
" <td>-79.244457</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Giant Tiger</td>\n",
" <td>43.727447</td>\n",
" <td>-79.266240</td>\n",
" <td>Department Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>26</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.726895</td>\n",
" <td>-79.266157</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>27</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Hakka No.1</td>\n",
" <td>43.727688</td>\n",
" <td>-79.266057</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Dollarama</td>\n",
" <td>43.726904</td>\n",
" <td>-79.265886</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>29</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Kennedy GO Station</td>\n",
" <td>43.732275</td>\n",
" <td>-79.262418</td>\n",
" <td>Train Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>30</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Dollarama</td>\n",
" <td>43.726596</td>\n",
" <td>-79.266830</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>31</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Kennedy Station Passenger Pickup</td>\n",
" <td>43.732009</td>\n",
" <td>-79.264537</td>\n",
" <td>Bus Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>32</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Dairy Queen</td>\n",
" <td>43.710378</td>\n",
" <td>-79.290701</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>33</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Warden Ave &amp; St. Clair Ave E</td>\n",
" <td>43.712057</td>\n",
" <td>-79.281005</td>\n",
" <td>Intersection</td>\n",
" </tr>\n",
" <tr>\n",
" <th>34</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>TTC Bus #68 Warden</td>\n",
" <td>43.711778</td>\n",
" <td>-79.279714</td>\n",
" <td>Bus Line</td>\n",
" </tr>\n",
" <tr>\n",
" <th>35</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Warden Subway Station</td>\n",
" <td>43.711229</td>\n",
" <td>-79.279602</td>\n",
" <td>Metro Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>36</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>TTC Bus 102 Markham Road</td>\n",
" <td>43.711381</td>\n",
" <td>-79.279588</td>\n",
" <td>Bus Line</td>\n",
" </tr>\n",
" <tr>\n",
" <th>37</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Warden Station Bus Loop</td>\n",
" <td>43.711241</td>\n",
" <td>-79.279576</td>\n",
" <td>Bus Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>38</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Bakery On The Go</td>\n",
" <td>43.711271</td>\n",
" <td>-79.279506</td>\n",
" <td>Bakery</td>\n",
" </tr>\n",
" <tr>\n",
" <th>39</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Cafe on the go</td>\n",
" <td>43.711151</td>\n",
" <td>-79.279469</td>\n",
" <td>Bakery</td>\n",
" </tr>\n",
" <tr>\n",
" <th>40</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Clairlea Futbol Centre</td>\n",
" <td>43.715234</td>\n",
" <td>-79.286506</td>\n",
" <td>Soccer Field</td>\n",
" </tr>\n",
" <tr>\n",
" <th>41</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>43.716316</td>\n",
" <td>-79.239476</td>\n",
" <td>Have A Nap Motel</td>\n",
" <td>43.718256</td>\n",
" <td>-79.240135</td>\n",
" <td>Motel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>42</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>43.716316</td>\n",
" <td>-79.239476</td>\n",
" <td>Vincent's Spot</td>\n",
" <td>43.717002</td>\n",
" <td>-79.242353</td>\n",
" <td>American Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>43</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>The Birchcliff</td>\n",
" <td>43.691666</td>\n",
" <td>-79.264532</td>\n",
" <td>Café</td>\n",
" </tr>\n",
" <tr>\n",
" <th>44</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Birchmount Community Centre</td>\n",
" <td>43.695175</td>\n",
" <td>-79.262161</td>\n",
" <td>General Entertainment</td>\n",
" </tr>\n",
" <tr>\n",
" <th>45</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Scarborough Gardens</td>\n",
" <td>43.694647</td>\n",
" <td>-79.262230</td>\n",
" <td>Skating Rink</td>\n",
" </tr>\n",
" <tr>\n",
" <th>46</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Birchmount Stadium</td>\n",
" <td>43.695323</td>\n",
" <td>-79.261293</td>\n",
" <td>College Stadium</td>\n",
" </tr>\n",
" <tr>\n",
" <th>47</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Kairali</td>\n",
" <td>43.754768</td>\n",
" <td>-79.277199</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>48</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Kim Kim restaurant</td>\n",
" <td>43.753833</td>\n",
" <td>-79.276611</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>49</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>El Pulgarcito</td>\n",
" <td>43.754790</td>\n",
" <td>-79.277064</td>\n",
" <td>Latin American Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Karaikudi Chettinad South Indian Restaurant</td>\n",
" <td>43.756042</td>\n",
" <td>-79.276276</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>51</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Big Al's Pet Supercentre</td>\n",
" <td>43.759279</td>\n",
" <td>-79.278325</td>\n",
" <td>Pet Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>52</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Pho Vietnam</td>\n",
" <td>43.757770</td>\n",
" <td>-79.278572</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>53</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Mill St. Brewery</td>\n",
" <td>43.759472</td>\n",
" <td>-79.271121</td>\n",
" <td>Brewery</td>\n",
" </tr>\n",
" <tr>\n",
" <th>54</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Salvation Army Thrift Store</td>\n",
" <td>43.755782</td>\n",
" <td>-79.276208</td>\n",
" <td>Thrift / Vintage Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>55</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Blinds To Go</td>\n",
" <td>43.757147</td>\n",
" <td>-79.278073</td>\n",
" <td>Furniture / Home Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>56</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Wexford Restaurant</td>\n",
" <td>43.746030</td>\n",
" <td>-79.293843</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Subway</td>\n",
" <td>43.746008</td>\n",
" <td>-79.293238</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>58</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Lebanese bakery</td>\n",
" <td>43.746701</td>\n",
" <td>-79.292896</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>59</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Wexford Heights Plaza</td>\n",
" <td>43.746136</td>\n",
" <td>-79.293782</td>\n",
" <td>Shopping Mall</td>\n",
" </tr>\n",
" <tr>\n",
" <th>60</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Scarborough Garage Door Repair</td>\n",
" <td>43.751288</td>\n",
" <td>-79.301508</td>\n",
" <td>Auto Garage</td>\n",
" </tr>\n",
" <tr>\n",
" <th>61</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Sequoia Lounge</td>\n",
" <td>43.745645</td>\n",
" <td>-79.295737</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>62</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Panagio's Breakfast &amp; Lunch</td>\n",
" <td>43.792370</td>\n",
" <td>-79.260203</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>63</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Twilight</td>\n",
" <td>43.791999</td>\n",
" <td>-79.258584</td>\n",
" <td>Lounge</td>\n",
" </tr>\n",
" <tr>\n",
" <th>64</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Subway</td>\n",
" <td>43.792823</td>\n",
" <td>-79.259681</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>65</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Mark's</td>\n",
" <td>43.791179</td>\n",
" <td>-79.259714</td>\n",
" <td>Clothing Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>66</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Royal Chinese Seafood Restaurant</td>\n",
" <td>43.798496</td>\n",
" <td>-79.262196</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>67</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Remezzo Italian Bistro</td>\n",
" <td>43.778649</td>\n",
" <td>-79.308264</td>\n",
" <td>Italian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>68</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>The Royal Chinese Restaurant 避風塘小炒</td>\n",
" <td>43.780505</td>\n",
" <td>-79.298844</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>69</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Eight Noodles</td>\n",
" <td>43.778234</td>\n",
" <td>-79.308299</td>\n",
" <td>Noodle House</td>\n",
" </tr>\n",
" <tr>\n",
" <th>70</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Kub Khao</td>\n",
" <td>43.780438</td>\n",
" <td>-79.299837</td>\n",
" <td>Thai Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>71</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Little Caesars</td>\n",
" <td>43.780563</td>\n",
" <td>-79.298624</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>72</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Popeyes</td>\n",
" <td>43.780476</td>\n",
" <td>-79.298460</td>\n",
" <td>Fried Chicken Joint</td>\n",
" </tr>\n",
" <tr>\n",
" <th>73</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Eaton Centre USA</td>\n",
" <td>43.783572</td>\n",
" <td>-79.304916</td>\n",
" <td>Shopping Mall</td>\n",
" </tr>\n",
" <tr>\n",
" <th>74</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>KFC</td>\n",
" <td>43.779440</td>\n",
" <td>-79.303371</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>75</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Gusto Pizza</td>\n",
" <td>43.783607</td>\n",
" <td>-79.298983</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>76</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" <td>Port Royal Park</td>\n",
" <td>43.815477</td>\n",
" <td>-79.289773</td>\n",
" <td>Park</td>\n",
" </tr>\n",
" <tr>\n",
" <th>77</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" <td>Milliken Public School Playground</td>\n",
" <td>43.815383</td>\n",
" <td>-79.289867</td>\n",
" <td>Playground</td>\n",
" </tr>\n",
" <tr>\n",
" <th>78</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Mr Congee Chinese Cuisine 龍粥記</td>\n",
" <td>43.798879</td>\n",
" <td>-79.318335</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>79</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Phoenix Restaurant 金鳳餐廳</td>\n",
" <td>43.798198</td>\n",
" <td>-79.318432</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>80</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Price Chopper</td>\n",
" <td>43.799445</td>\n",
" <td>-79.318563</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>81</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Subway</td>\n",
" <td>43.798983</td>\n",
" <td>-79.318838</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>82</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.798281</td>\n",
" <td>-79.318317</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>83</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Shoppers Drug Mart</td>\n",
" <td>43.799670</td>\n",
" <td>-79.319315</td>\n",
" <td>Pharmacy</td>\n",
" </tr>\n",
" <tr>\n",
" <th>84</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>KFC</td>\n",
" <td>43.798938</td>\n",
" <td>-79.318854</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>85</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Yamamoto Japanese Cuisine 山本盛世</td>\n",
" <td>43.798589</td>\n",
" <td>-79.318558</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>86</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>McDonald's</td>\n",
" <td>43.798880</td>\n",
" <td>-79.318724</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>87</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Pizza Pizza</td>\n",
" <td>43.797909</td>\n",
" <td>-79.318113</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>88</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Coffee Time</td>\n",
" <td>43.797952</td>\n",
" <td>-79.318678</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>89</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Eggsmart</td>\n",
" <td>43.796375</td>\n",
" <td>-79.318681</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>90</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Black's Photography</td>\n",
" <td>43.797292</td>\n",
" <td>-79.319332</td>\n",
" <td>Camera Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>91</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Nantha's Bakery</td>\n",
" <td>43.796430</td>\n",
" <td>-79.319151</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Neighborhood Latitude \\\n",
"0 RougeMalvern 43.806686 \n",
"1 RougeMalvern 43.806686 \n",
"2 Highland CreekRouge HillPort Union 43.784535 \n",
"3 Highland CreekRouge HillPort Union 43.784535 \n",
"4 GuildwoodMorningsideWest Hill 43.763573 \n",
"5 GuildwoodMorningsideWest Hill 43.763573 \n",
"6 GuildwoodMorningsideWest Hill 43.763573 \n",
"7 GuildwoodMorningsideWest Hill 43.763573 \n",
"8 GuildwoodMorningsideWest Hill 43.763573 \n",
"9 GuildwoodMorningsideWest Hill 43.763573 \n",
"10 GuildwoodMorningsideWest Hill 43.763573 \n",
"11 Woburn 43.770992 \n",
"12 Woburn 43.770992 \n",
"13 Woburn 43.770992 \n",
"14 Woburn 43.770992 \n",
"15 Cedarbrae 43.773136 \n",
"16 Cedarbrae 43.773136 \n",
"17 Cedarbrae 43.773136 \n",
"18 Cedarbrae 43.773136 \n",
"19 Cedarbrae 43.773136 \n",
"20 Cedarbrae 43.773136 \n",
"21 Cedarbrae 43.773136 \n",
"22 Scarborough Village 43.744734 \n",
"23 Scarborough Village 43.744734 \n",
"24 Scarborough Village 43.744734 \n",
"25 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"26 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"27 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"28 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"29 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"30 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"31 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"32 ClairleaGolden MileOakridge 43.711112 \n",
"33 ClairleaGolden MileOakridge 43.711112 \n",
"34 ClairleaGolden MileOakridge 43.711112 \n",
"35 ClairleaGolden MileOakridge 43.711112 \n",
"36 ClairleaGolden MileOakridge 43.711112 \n",
"37 ClairleaGolden MileOakridge 43.711112 \n",
"38 ClairleaGolden MileOakridge 43.711112 \n",
"39 ClairleaGolden MileOakridge 43.711112 \n",
"40 ClairleaGolden MileOakridge 43.711112 \n",
"41 CliffcrestCliffsideScarborough Village West 43.716316 \n",
"42 CliffcrestCliffsideScarborough Village West 43.716316 \n",
"43 Birch CliffCliffside West 43.692657 \n",
"44 Birch CliffCliffside West 43.692657 \n",
"45 Birch CliffCliffside West 43.692657 \n",
"46 Birch CliffCliffside West 43.692657 \n",
"47 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"48 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"49 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"50 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"51 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"52 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"53 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"54 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"55 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"56 MaryvaleWexford 43.750072 \n",
"57 MaryvaleWexford 43.750072 \n",
"58 MaryvaleWexford 43.750072 \n",
"59 MaryvaleWexford 43.750072 \n",
"60 MaryvaleWexford 43.750072 \n",
"61 MaryvaleWexford 43.750072 \n",
"62 Agincourt 43.794200 \n",
"63 Agincourt 43.794200 \n",
"64 Agincourt 43.794200 \n",
"65 Agincourt 43.794200 \n",
"66 Agincourt 43.794200 \n",
"67 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"68 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"69 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"70 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"71 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"72 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"73 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"74 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"75 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"76 Agincourt NorthL'Amoreaux EastMillikenSteeles ... 43.815252 \n",
"77 Agincourt NorthL'Amoreaux EastMillikenSteeles ... 43.815252 \n",
"78 L'Amoreaux WestSteeles West 43.799525 \n",
"79 L'Amoreaux WestSteeles West 43.799525 \n",
"80 L'Amoreaux WestSteeles West 43.799525 \n",
"81 L'Amoreaux WestSteeles West 43.799525 \n",
"82 L'Amoreaux WestSteeles West 43.799525 \n",
"83 L'Amoreaux WestSteeles West 43.799525 \n",
"84 L'Amoreaux WestSteeles West 43.799525 \n",
"85 L'Amoreaux WestSteeles West 43.799525 \n",
"86 L'Amoreaux WestSteeles West 43.799525 \n",
"87 L'Amoreaux WestSteeles West 43.799525 \n",
"88 L'Amoreaux WestSteeles West 43.799525 \n",
"89 L'Amoreaux WestSteeles West 43.799525 \n",
"90 L'Amoreaux WestSteeles West 43.799525 \n",
"91 L'Amoreaux WestSteeles West 43.799525 \n",
"\n",
" Neighborhood Longitude Venue \\\n",
"0 -79.194353 Wendy's \n",
"1 -79.194353 Interprovincial Group \n",
"2 -79.160497 Royal Canadian Legion \n",
"3 -79.160497 Affordable Toronto Movers \n",
"4 -79.188711 Swiss Chalet Rotisserie & Grill \n",
"5 -79.188711 G & G Electronics \n",
"6 -79.188711 Marina Spa \n",
"7 -79.188711 Big Bite Burrito \n",
"8 -79.188711 Enterprise Rent-A-Car \n",
"9 -79.188711 Woburn Medical Centre \n",
"10 -79.188711 Eggsmart \n",
"11 -79.216917 Starbucks \n",
"12 -79.216917 Tim Hortons \n",
"13 -79.216917 Korean Grill House \n",
"14 -79.216917 Al-Hamd Biryani & Pizza \n",
"15 -79.239476 Federick Restaurant \n",
"16 -79.239476 Drupati's Roti & Doubles \n",
"17 -79.239476 Thai One On \n",
"18 -79.239476 Centennial Recreation Centre \n",
"19 -79.239476 TD Canada Trust \n",
"20 -79.239476 B&A Bakery \n",
"21 -79.239476 Popeyes Louisiana Kitchen \n",
"22 -79.239476 McCowan Park \n",
"23 -79.239476 Tumbe Cafe \n",
"24 -79.239476 Elane Barbers \n",
"25 -79.262029 Giant Tiger \n",
"26 -79.262029 Tim Hortons \n",
"27 -79.262029 Hakka No.1 \n",
"28 -79.262029 Dollarama \n",
"29 -79.262029 Kennedy GO Station \n",
"30 -79.262029 Dollarama \n",
"31 -79.262029 Kennedy Station Passenger Pickup \n",
"32 -79.284577 Dairy Queen \n",
"33 -79.284577 Warden Ave & St. Clair Ave E \n",
"34 -79.284577 TTC Bus #68 Warden \n",
"35 -79.284577 Warden Subway Station \n",
"36 -79.284577 TTC Bus 102 Markham Road \n",
"37 -79.284577 Warden Station Bus Loop \n",
"38 -79.284577 Bakery On The Go \n",
"39 -79.284577 Cafe on the go \n",
"40 -79.284577 Clairlea Futbol Centre \n",
"41 -79.239476 Have A Nap Motel \n",
"42 -79.239476 Vincent's Spot \n",
"43 -79.264848 The Birchcliff \n",
"44 -79.264848 Birchmount Community Centre \n",
"45 -79.264848 Scarborough Gardens \n",
"46 -79.264848 Birchmount Stadium \n",
"47 -79.273304 Kairali \n",
"48 -79.273304 Kim Kim restaurant \n",
"49 -79.273304 El Pulgarcito \n",
"50 -79.273304 Karaikudi Chettinad South Indian Restaurant \n",
"51 -79.273304 Big Al's Pet Supercentre \n",
"52 -79.273304 Pho Vietnam \n",
"53 -79.273304 Mill St. Brewery \n",
"54 -79.273304 Salvation Army Thrift Store \n",
"55 -79.273304 Blinds To Go \n",
"56 -79.295849 Wexford Restaurant \n",
"57 -79.295849 Subway \n",
"58 -79.295849 Lebanese bakery \n",
"59 -79.295849 Wexford Heights Plaza \n",
"60 -79.295849 Scarborough Garage Door Repair \n",
"61 -79.295849 Sequoia Lounge \n",
"62 -79.262029 Panagio's Breakfast & Lunch \n",
"63 -79.262029 Twilight \n",
"64 -79.262029 Subway \n",
"65 -79.262029 Mark's \n",
"66 -79.262029 Royal Chinese Seafood Restaurant \n",
"67 -79.304302 Remezzo Italian Bistro \n",
"68 -79.304302 The Royal Chinese Restaurant 避風塘小炒 \n",
"69 -79.304302 Eight Noodles \n",
"70 -79.304302 Kub Khao \n",
"71 -79.304302 Little Caesars \n",
"72 -79.304302 Popeyes \n",
"73 -79.304302 Eaton Centre USA \n",
"74 -79.304302 KFC \n",
"75 -79.304302 Gusto Pizza \n",
"76 -79.284577 Port Royal Park \n",
"77 -79.284577 Milliken Public School Playground \n",
"78 -79.318389 Mr Congee Chinese Cuisine 龍粥記 \n",
"79 -79.318389 Phoenix Restaurant 金鳳餐廳 \n",
"80 -79.318389 Price Chopper \n",
"81 -79.318389 Subway \n",
"82 -79.318389 Tim Hortons \n",
"83 -79.318389 Shoppers Drug Mart \n",
"84 -79.318389 KFC \n",
"85 -79.318389 Yamamoto Japanese Cuisine 山本盛世 \n",
"86 -79.318389 McDonald's \n",
"87 -79.318389 Pizza Pizza \n",
"88 -79.318389 Coffee Time \n",
"89 -79.318389 Eggsmart \n",
"90 -79.318389 Black's Photography \n",
"91 -79.318389 Nantha's Bakery \n",
"\n",
" Venue Latitude Venue Longitude Venue Category \n",
"0 43.807448 -79.199056 Fast Food Restaurant \n",
"1 43.805630 -79.200378 Print Shop \n",
"2 43.782533 -79.163085 Bar \n",
"3 43.787919 -79.162977 Moving Target \n",
"4 43.767697 -79.189914 Pizza Place \n",
"5 43.765309 -79.191537 Electronics Store \n",
"6 43.766000 -79.191000 Spa \n",
"7 43.766299 -79.190720 Mexican Restaurant \n",
"8 43.764076 -79.193406 Rental Car Location \n",
"9 43.766631 -79.192286 Medical Center \n",
"10 43.767800 -79.190466 Breakfast Spot \n",
"11 43.770037 -79.221156 Coffee Shop \n",
"12 43.770827 -79.223078 Coffee Shop \n",
"13 43.770812 -79.214502 Korean Restaurant \n",
"14 43.767585 -79.219570 Indian Restaurant \n",
"15 43.774697 -79.241142 Hakka Restaurant \n",
"16 43.775222 -79.241678 Caribbean Restaurant \n",
"17 43.774468 -79.241268 Thai Restaurant \n",
"18 43.774593 -79.236500 Athletics & Sports \n",
"19 43.774952 -79.241343 Bank \n",
"20 43.774391 -79.243877 Bakery \n",
"21 43.775930 -79.235328 Fried Chicken Joint \n",
"22 43.745089 -79.239336 Playground \n",
"23 43.744058 -79.244021 Grocery Store \n",
"24 43.743706 -79.244457 Cosmetics Shop \n",
"25 43.727447 -79.266240 Department Store \n",
"26 43.726895 -79.266157 Coffee Shop \n",
"27 43.727688 -79.266057 Chinese Restaurant \n",
"28 43.726904 -79.265886 Discount Store \n",
"29 43.732275 -79.262418 Train Station \n",
"30 43.726596 -79.266830 Discount Store \n",
"31 43.732009 -79.264537 Bus Station \n",
"32 43.710378 -79.290701 Fast Food Restaurant \n",
"33 43.712057 -79.281005 Intersection \n",
"34 43.711778 -79.279714 Bus Line \n",
"35 43.711229 -79.279602 Metro Station \n",
"36 43.711381 -79.279588 Bus Line \n",
"37 43.711241 -79.279576 Bus Station \n",
"38 43.711271 -79.279506 Bakery \n",
"39 43.711151 -79.279469 Bakery \n",
"40 43.715234 -79.286506 Soccer Field \n",
"41 43.718256 -79.240135 Motel \n",
"42 43.717002 -79.242353 American Restaurant \n",
"43 43.691666 -79.264532 Café \n",
"44 43.695175 -79.262161 General Entertainment \n",
"45 43.694647 -79.262230 Skating Rink \n",
"46 43.695323 -79.261293 College Stadium \n",
"47 43.754768 -79.277199 Indian Restaurant \n",
"48 43.753833 -79.276611 Chinese Restaurant \n",
"49 43.754790 -79.277064 Latin American Restaurant \n",
"50 43.756042 -79.276276 Indian Restaurant \n",
"51 43.759279 -79.278325 Pet Store \n",
"52 43.757770 -79.278572 Vietnamese Restaurant \n",
"53 43.759472 -79.271121 Brewery \n",
"54 43.755782 -79.276208 Thrift / Vintage Store \n",
"55 43.757147 -79.278073 Furniture / Home Store \n",
"56 43.746030 -79.293843 Breakfast Spot \n",
"57 43.746008 -79.293238 Sandwich Place \n",
"58 43.746701 -79.292896 Middle Eastern Restaurant \n",
"59 43.746136 -79.293782 Shopping Mall \n",
"60 43.751288 -79.301508 Auto Garage \n",
"61 43.745645 -79.295737 Middle Eastern Restaurant \n",
"62 43.792370 -79.260203 Breakfast Spot \n",
"63 43.791999 -79.258584 Lounge \n",
"64 43.792823 -79.259681 Sandwich Place \n",
"65 43.791179 -79.259714 Clothing Store \n",
"66 43.798496 -79.262196 Chinese Restaurant \n",
"67 43.778649 -79.308264 Italian Restaurant \n",
"68 43.780505 -79.298844 Chinese Restaurant \n",
"69 43.778234 -79.308299 Noodle House \n",
"70 43.780438 -79.299837 Thai Restaurant \n",
"71 43.780563 -79.298624 Pizza Place \n",
"72 43.780476 -79.298460 Fried Chicken Joint \n",
"73 43.783572 -79.304916 Shopping Mall \n",
"74 43.779440 -79.303371 Fast Food Restaurant \n",
"75 43.783607 -79.298983 Pizza Place \n",
"76 43.815477 -79.289773 Park \n",
"77 43.815383 -79.289867 Playground \n",
"78 43.798879 -79.318335 Chinese Restaurant \n",
"79 43.798198 -79.318432 Chinese Restaurant \n",
"80 43.799445 -79.318563 Grocery Store \n",
"81 43.798983 -79.318838 Sandwich Place \n",
"82 43.798281 -79.318317 Coffee Shop \n",
"83 43.799670 -79.319315 Pharmacy \n",
"84 43.798938 -79.318854 Fast Food Restaurant \n",
"85 43.798589 -79.318558 Japanese Restaurant \n",
"86 43.798880 -79.318724 Fast Food Restaurant \n",
"87 43.797909 -79.318113 Pizza Place \n",
"88 43.797952 -79.318678 Coffee Shop \n",
"89 43.796375 -79.318681 Breakfast Spot \n",
"90 43.797292 -79.319332 Camera Store \n",
"91 43.796430 -79.319151 Indian Restaurant "
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_venues"
]
},
{
"cell_type": "code",
"execution_count": 32,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>M1S</td>\n",
" <td>Scarborough</td>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>M1T</td>\n",
" <td>Scarborough</td>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>M1V</td>\n",
" <td>Scarborough</td>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>M1W</td>\n",
" <td>Scarborough</td>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>M1X</td>\n",
" <td>Scarborough</td>\n",
" <td>Upper Rouge</td>\n",
" <td>43.836125</td>\n",
" <td>-79.205636</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood \\\n",
"12 M1S Scarborough Agincourt \n",
"13 M1T Scarborough Clarks CornersSullivanTam O'Shanter \n",
"14 M1V Scarborough Agincourt NorthL'Amoreaux EastMillikenSteeles ... \n",
"15 M1W Scarborough L'Amoreaux WestSteeles West \n",
"16 M1X Scarborough Upper Rouge \n",
"\n",
" Latitude Longitude \n",
"12 43.794200 -79.262029 \n",
"13 43.781638 -79.304302 \n",
"14 43.815252 -79.284577 \n",
"15 43.799525 -79.318389 \n",
"16 43.836125 -79.205636 "
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_data.tail()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighbourhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>M1R</td>\n",
" <td>Scarborough</td>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>M1S</td>\n",
" <td>Scarborough</td>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>M1T</td>\n",
" <td>Scarborough</td>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>M1V</td>\n",
" <td>Scarborough</td>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>M1W</td>\n",
" <td>Scarborough</td>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighbourhood \\\n",
"11 M1R Scarborough MaryvaleWexford \n",
"12 M1S Scarborough Agincourt \n",
"13 M1T Scarborough Clarks CornersSullivanTam O'Shanter \n",
"14 M1V Scarborough Agincourt NorthL'Amoreaux EastMillikenSteeles ... \n",
"15 M1W Scarborough L'Amoreaux WestSteeles West \n",
"\n",
" Latitude Longitude \n",
"11 43.750072 -79.295849 \n",
"12 43.794200 -79.262029 \n",
"13 43.781638 -79.304302 \n",
"14 43.815252 -79.284577 \n",
"15 43.799525 -79.318389 "
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_data.drop(index=16,axis=0,inplace=True)\n",
"Scarborough_data.tail()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Drop Neighbourhoods with no venues"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(92, 7)\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>Neighborhood Latitude</th>\n",
" <th>Neighborhood Longitude</th>\n",
" <th>Venue</th>\n",
" <th>Venue Latitude</th>\n",
" <th>Venue Longitude</th>\n",
" <th>Venue Category</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Wendy's</td>\n",
" <td>43.807448</td>\n",
" <td>-79.199056</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Interprovincial Group</td>\n",
" <td>43.805630</td>\n",
" <td>-79.200378</td>\n",
" <td>Print Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Royal Canadian Legion</td>\n",
" <td>43.782533</td>\n",
" <td>-79.163085</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Affordable Toronto Movers</td>\n",
" <td>43.787919</td>\n",
" <td>-79.162977</td>\n",
" <td>Moving Target</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Swiss Chalet Rotisserie &amp; Grill</td>\n",
" <td>43.767697</td>\n",
" <td>-79.189914</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Neighborhood Latitude \\\n",
"0 RougeMalvern 43.806686 \n",
"1 RougeMalvern 43.806686 \n",
"2 Highland CreekRouge HillPort Union 43.784535 \n",
"3 Highland CreekRouge HillPort Union 43.784535 \n",
"4 GuildwoodMorningsideWest Hill 43.763573 \n",
"\n",
" Neighborhood Longitude Venue Venue Latitude \\\n",
"0 -79.194353 Wendy's 43.807448 \n",
"1 -79.194353 Interprovincial Group 43.805630 \n",
"2 -79.160497 Royal Canadian Legion 43.782533 \n",
"3 -79.160497 Affordable Toronto Movers 43.787919 \n",
"4 -79.188711 Swiss Chalet Rotisserie & Grill 43.767697 \n",
"\n",
" Venue Longitude Venue Category \n",
"0 -79.199056 Fast Food Restaurant \n",
"1 -79.200378 Print Shop \n",
"2 -79.163085 Bar \n",
"3 -79.162977 Moving Target \n",
"4 -79.189914 Pizza Place "
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print(Scarborough_venues.shape)\n",
"Scarborough_venues.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Groupby the venues by Neigbourhood"
]
},
{
"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>Neighborhood</th>\n",
" <th>Neighborhood Latitude</th>\n",
" <th>Neighborhood Longitude</th>\n",
" <th>Venue</th>\n",
" <th>Venue Latitude</th>\n",
" <th>Venue Longitude</th>\n",
" <th>Venue Category</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Wendy's</td>\n",
" <td>43.807448</td>\n",
" <td>-79.199056</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>Interprovincial Group</td>\n",
" <td>43.805630</td>\n",
" <td>-79.200378</td>\n",
" <td>Print Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Royal Canadian Legion</td>\n",
" <td>43.782533</td>\n",
" <td>-79.163085</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>Affordable Toronto Movers</td>\n",
" <td>43.787919</td>\n",
" <td>-79.162977</td>\n",
" <td>Moving Target</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Swiss Chalet Rotisserie &amp; Grill</td>\n",
" <td>43.767697</td>\n",
" <td>-79.189914</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>G &amp; G Electronics</td>\n",
" <td>43.765309</td>\n",
" <td>-79.191537</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Marina Spa</td>\n",
" <td>43.766000</td>\n",
" <td>-79.191000</td>\n",
" <td>Spa</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Big Bite Burrito</td>\n",
" <td>43.766299</td>\n",
" <td>-79.190720</td>\n",
" <td>Mexican Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>Enterprise Rent-A-Car</td>\n",
" <td>43.764076</td>\n",
" <td>-79.193406</td>\n",
" <td>Rental Car Location</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Starbucks</td>\n",
" <td>43.770037</td>\n",
" <td>-79.221156</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.770827</td>\n",
" <td>-79.223078</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Korean Grill House</td>\n",
" <td>43.770812</td>\n",
" <td>-79.214502</td>\n",
" <td>Korean Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>Al-Hamd Biryani &amp; Pizza</td>\n",
" <td>43.767585</td>\n",
" <td>-79.219570</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Federick Restaurant</td>\n",
" <td>43.774697</td>\n",
" <td>-79.241142</td>\n",
" <td>Hakka Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Drupati's Roti &amp; Doubles</td>\n",
" <td>43.775222</td>\n",
" <td>-79.241678</td>\n",
" <td>Caribbean Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Thai One On</td>\n",
" <td>43.774468</td>\n",
" <td>-79.241268</td>\n",
" <td>Thai Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>Centennial Recreation Centre</td>\n",
" <td>43.774593</td>\n",
" <td>-79.236500</td>\n",
" <td>Athletics &amp; Sports</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>TD Canada Trust</td>\n",
" <td>43.774952</td>\n",
" <td>-79.241343</td>\n",
" <td>Bank</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>McCowan Park</td>\n",
" <td>43.745089</td>\n",
" <td>-79.239336</td>\n",
" <td>Playground</td>\n",
" </tr>\n",
" <tr>\n",
" <th>23</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>Tumbe Cafe</td>\n",
" <td>43.744058</td>\n",
" <td>-79.244021</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>24</th>\n",
" <td>Scarborough Village</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>Elane Barbers</td>\n",
" <td>43.743706</td>\n",
" <td>-79.244457</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>25</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Giant Tiger</td>\n",
" <td>43.727447</td>\n",
" <td>-79.266240</td>\n",
" <td>Department Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>26</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.726895</td>\n",
" <td>-79.266157</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>27</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Hakka No.1</td>\n",
" <td>43.727688</td>\n",
" <td>-79.266057</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>28</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Dollarama</td>\n",
" <td>43.726904</td>\n",
" <td>-79.265886</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>29</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>Kennedy GO Station</td>\n",
" <td>43.732275</td>\n",
" <td>-79.262418</td>\n",
" <td>Train Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>32</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Dairy Queen</td>\n",
" <td>43.710378</td>\n",
" <td>-79.290701</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>33</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Warden Ave &amp; St. Clair Ave E</td>\n",
" <td>43.712057</td>\n",
" <td>-79.281005</td>\n",
" <td>Intersection</td>\n",
" </tr>\n",
" <tr>\n",
" <th>34</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>TTC Bus #68 Warden</td>\n",
" <td>43.711778</td>\n",
" <td>-79.279714</td>\n",
" <td>Bus Line</td>\n",
" </tr>\n",
" <tr>\n",
" <th>35</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>Warden Subway Station</td>\n",
" <td>43.711229</td>\n",
" <td>-79.279602</td>\n",
" <td>Metro Station</td>\n",
" </tr>\n",
" <tr>\n",
" <th>36</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>TTC Bus 102 Markham Road</td>\n",
" <td>43.711381</td>\n",
" <td>-79.279588</td>\n",
" <td>Bus Line</td>\n",
" </tr>\n",
" <tr>\n",
" <th>41</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>43.716316</td>\n",
" <td>-79.239476</td>\n",
" <td>Have A Nap Motel</td>\n",
" <td>43.718256</td>\n",
" <td>-79.240135</td>\n",
" <td>Motel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>42</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>43.716316</td>\n",
" <td>-79.239476</td>\n",
" <td>Vincent's Spot</td>\n",
" <td>43.717002</td>\n",
" <td>-79.242353</td>\n",
" <td>American Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>43</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>The Birchcliff</td>\n",
" <td>43.691666</td>\n",
" <td>-79.264532</td>\n",
" <td>Café</td>\n",
" </tr>\n",
" <tr>\n",
" <th>44</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Birchmount Community Centre</td>\n",
" <td>43.695175</td>\n",
" <td>-79.262161</td>\n",
" <td>General Entertainment</td>\n",
" </tr>\n",
" <tr>\n",
" <th>45</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Scarborough Gardens</td>\n",
" <td>43.694647</td>\n",
" <td>-79.262230</td>\n",
" <td>Skating Rink</td>\n",
" </tr>\n",
" <tr>\n",
" <th>46</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>Birchmount Stadium</td>\n",
" <td>43.695323</td>\n",
" <td>-79.261293</td>\n",
" <td>College Stadium</td>\n",
" </tr>\n",
" <tr>\n",
" <th>47</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Kairali</td>\n",
" <td>43.754768</td>\n",
" <td>-79.277199</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>48</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Kim Kim restaurant</td>\n",
" <td>43.753833</td>\n",
" <td>-79.276611</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>49</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>El Pulgarcito</td>\n",
" <td>43.754790</td>\n",
" <td>-79.277064</td>\n",
" <td>Latin American Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>50</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Karaikudi Chettinad South Indian Restaurant</td>\n",
" <td>43.756042</td>\n",
" <td>-79.276276</td>\n",
" <td>Indian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>51</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>43.757410</td>\n",
" <td>-79.273304</td>\n",
" <td>Big Al's Pet Supercentre</td>\n",
" <td>43.759279</td>\n",
" <td>-79.278325</td>\n",
" <td>Pet Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>56</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Wexford Restaurant</td>\n",
" <td>43.746030</td>\n",
" <td>-79.293843</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>57</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Subway</td>\n",
" <td>43.746008</td>\n",
" <td>-79.293238</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>58</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Lebanese bakery</td>\n",
" <td>43.746701</td>\n",
" <td>-79.292896</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>59</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Wexford Heights Plaza</td>\n",
" <td>43.746136</td>\n",
" <td>-79.293782</td>\n",
" <td>Shopping Mall</td>\n",
" </tr>\n",
" <tr>\n",
" <th>60</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>Scarborough Garage Door Repair</td>\n",
" <td>43.751288</td>\n",
" <td>-79.301508</td>\n",
" <td>Auto Garage</td>\n",
" </tr>\n",
" <tr>\n",
" <th>62</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Panagio's Breakfast &amp; Lunch</td>\n",
" <td>43.792370</td>\n",
" <td>-79.260203</td>\n",
" <td>Breakfast Spot</td>\n",
" </tr>\n",
" <tr>\n",
" <th>63</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Twilight</td>\n",
" <td>43.791999</td>\n",
" <td>-79.258584</td>\n",
" <td>Lounge</td>\n",
" </tr>\n",
" <tr>\n",
" <th>64</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Subway</td>\n",
" <td>43.792823</td>\n",
" <td>-79.259681</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>65</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Mark's</td>\n",
" <td>43.791179</td>\n",
" <td>-79.259714</td>\n",
" <td>Clothing Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>66</th>\n",
" <td>Agincourt</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>Royal Chinese Seafood Restaurant</td>\n",
" <td>43.798496</td>\n",
" <td>-79.262196</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>67</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Remezzo Italian Bistro</td>\n",
" <td>43.778649</td>\n",
" <td>-79.308264</td>\n",
" <td>Italian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>68</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>The Royal Chinese Restaurant 避風塘小炒</td>\n",
" <td>43.780505</td>\n",
" <td>-79.298844</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>69</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Eight Noodles</td>\n",
" <td>43.778234</td>\n",
" <td>-79.308299</td>\n",
" <td>Noodle House</td>\n",
" </tr>\n",
" <tr>\n",
" <th>70</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Kub Khao</td>\n",
" <td>43.780438</td>\n",
" <td>-79.299837</td>\n",
" <td>Thai Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>71</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>Little Caesars</td>\n",
" <td>43.780563</td>\n",
" <td>-79.298624</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>76</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" <td>Port Royal Park</td>\n",
" <td>43.815477</td>\n",
" <td>-79.289773</td>\n",
" <td>Park</td>\n",
" </tr>\n",
" <tr>\n",
" <th>77</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" <td>Milliken Public School Playground</td>\n",
" <td>43.815383</td>\n",
" <td>-79.289867</td>\n",
" <td>Playground</td>\n",
" </tr>\n",
" <tr>\n",
" <th>78</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Mr Congee Chinese Cuisine 龍粥記</td>\n",
" <td>43.798879</td>\n",
" <td>-79.318335</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>79</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Phoenix Restaurant 金鳳餐廳</td>\n",
" <td>43.798198</td>\n",
" <td>-79.318432</td>\n",
" <td>Chinese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>80</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Price Chopper</td>\n",
" <td>43.799445</td>\n",
" <td>-79.318563</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>81</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Subway</td>\n",
" <td>43.798983</td>\n",
" <td>-79.318838</td>\n",
" <td>Sandwich Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>82</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>Tim Hortons</td>\n",
" <td>43.798281</td>\n",
" <td>-79.318317</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood Neighborhood Latitude \\\n",
"0 RougeMalvern 43.806686 \n",
"1 RougeMalvern 43.806686 \n",
"2 Highland CreekRouge HillPort Union 43.784535 \n",
"3 Highland CreekRouge HillPort Union 43.784535 \n",
"4 GuildwoodMorningsideWest Hill 43.763573 \n",
"5 GuildwoodMorningsideWest Hill 43.763573 \n",
"6 GuildwoodMorningsideWest Hill 43.763573 \n",
"7 GuildwoodMorningsideWest Hill 43.763573 \n",
"8 GuildwoodMorningsideWest Hill 43.763573 \n",
"11 Woburn 43.770992 \n",
"12 Woburn 43.770992 \n",
"13 Woburn 43.770992 \n",
"14 Woburn 43.770992 \n",
"15 Cedarbrae 43.773136 \n",
"16 Cedarbrae 43.773136 \n",
"17 Cedarbrae 43.773136 \n",
"18 Cedarbrae 43.773136 \n",
"19 Cedarbrae 43.773136 \n",
"22 Scarborough Village 43.744734 \n",
"23 Scarborough Village 43.744734 \n",
"24 Scarborough Village 43.744734 \n",
"25 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"26 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"27 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"28 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"29 East Birchmount ParkIonviewKennedy Park 43.727929 \n",
"32 ClairleaGolden MileOakridge 43.711112 \n",
"33 ClairleaGolden MileOakridge 43.711112 \n",
"34 ClairleaGolden MileOakridge 43.711112 \n",
"35 ClairleaGolden MileOakridge 43.711112 \n",
"36 ClairleaGolden MileOakridge 43.711112 \n",
"41 CliffcrestCliffsideScarborough Village West 43.716316 \n",
"42 CliffcrestCliffsideScarborough Village West 43.716316 \n",
"43 Birch CliffCliffside West 43.692657 \n",
"44 Birch CliffCliffside West 43.692657 \n",
"45 Birch CliffCliffside West 43.692657 \n",
"46 Birch CliffCliffside West 43.692657 \n",
"47 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"48 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"49 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"50 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"51 Dorset ParkScarborough Town CentreWexford Heights 43.757410 \n",
"56 MaryvaleWexford 43.750072 \n",
"57 MaryvaleWexford 43.750072 \n",
"58 MaryvaleWexford 43.750072 \n",
"59 MaryvaleWexford 43.750072 \n",
"60 MaryvaleWexford 43.750072 \n",
"62 Agincourt 43.794200 \n",
"63 Agincourt 43.794200 \n",
"64 Agincourt 43.794200 \n",
"65 Agincourt 43.794200 \n",
"66 Agincourt 43.794200 \n",
"67 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"68 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"69 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"70 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"71 Clarks CornersSullivanTam O'Shanter 43.781638 \n",
"76 Agincourt NorthL'Amoreaux EastMillikenSteeles ... 43.815252 \n",
"77 Agincourt NorthL'Amoreaux EastMillikenSteeles ... 43.815252 \n",
"78 L'Amoreaux WestSteeles West 43.799525 \n",
"79 L'Amoreaux WestSteeles West 43.799525 \n",
"80 L'Amoreaux WestSteeles West 43.799525 \n",
"81 L'Amoreaux WestSteeles West 43.799525 \n",
"82 L'Amoreaux WestSteeles West 43.799525 \n",
"\n",
" Neighborhood Longitude Venue \\\n",
"0 -79.194353 Wendy's \n",
"1 -79.194353 Interprovincial Group \n",
"2 -79.160497 Royal Canadian Legion \n",
"3 -79.160497 Affordable Toronto Movers \n",
"4 -79.188711 Swiss Chalet Rotisserie & Grill \n",
"5 -79.188711 G & G Electronics \n",
"6 -79.188711 Marina Spa \n",
"7 -79.188711 Big Bite Burrito \n",
"8 -79.188711 Enterprise Rent-A-Car \n",
"11 -79.216917 Starbucks \n",
"12 -79.216917 Tim Hortons \n",
"13 -79.216917 Korean Grill House \n",
"14 -79.216917 Al-Hamd Biryani & Pizza \n",
"15 -79.239476 Federick Restaurant \n",
"16 -79.239476 Drupati's Roti & Doubles \n",
"17 -79.239476 Thai One On \n",
"18 -79.239476 Centennial Recreation Centre \n",
"19 -79.239476 TD Canada Trust \n",
"22 -79.239476 McCowan Park \n",
"23 -79.239476 Tumbe Cafe \n",
"24 -79.239476 Elane Barbers \n",
"25 -79.262029 Giant Tiger \n",
"26 -79.262029 Tim Hortons \n",
"27 -79.262029 Hakka No.1 \n",
"28 -79.262029 Dollarama \n",
"29 -79.262029 Kennedy GO Station \n",
"32 -79.284577 Dairy Queen \n",
"33 -79.284577 Warden Ave & St. Clair Ave E \n",
"34 -79.284577 TTC Bus #68 Warden \n",
"35 -79.284577 Warden Subway Station \n",
"36 -79.284577 TTC Bus 102 Markham Road \n",
"41 -79.239476 Have A Nap Motel \n",
"42 -79.239476 Vincent's Spot \n",
"43 -79.264848 The Birchcliff \n",
"44 -79.264848 Birchmount Community Centre \n",
"45 -79.264848 Scarborough Gardens \n",
"46 -79.264848 Birchmount Stadium \n",
"47 -79.273304 Kairali \n",
"48 -79.273304 Kim Kim restaurant \n",
"49 -79.273304 El Pulgarcito \n",
"50 -79.273304 Karaikudi Chettinad South Indian Restaurant \n",
"51 -79.273304 Big Al's Pet Supercentre \n",
"56 -79.295849 Wexford Restaurant \n",
"57 -79.295849 Subway \n",
"58 -79.295849 Lebanese bakery \n",
"59 -79.295849 Wexford Heights Plaza \n",
"60 -79.295849 Scarborough Garage Door Repair \n",
"62 -79.262029 Panagio's Breakfast & Lunch \n",
"63 -79.262029 Twilight \n",
"64 -79.262029 Subway \n",
"65 -79.262029 Mark's \n",
"66 -79.262029 Royal Chinese Seafood Restaurant \n",
"67 -79.304302 Remezzo Italian Bistro \n",
"68 -79.304302 The Royal Chinese Restaurant 避風塘小炒 \n",
"69 -79.304302 Eight Noodles \n",
"70 -79.304302 Kub Khao \n",
"71 -79.304302 Little Caesars \n",
"76 -79.284577 Port Royal Park \n",
"77 -79.284577 Milliken Public School Playground \n",
"78 -79.318389 Mr Congee Chinese Cuisine 龍粥記 \n",
"79 -79.318389 Phoenix Restaurant 金鳳餐廳 \n",
"80 -79.318389 Price Chopper \n",
"81 -79.318389 Subway \n",
"82 -79.318389 Tim Hortons \n",
"\n",
" Venue Latitude Venue Longitude Venue Category \n",
"0 43.807448 -79.199056 Fast Food Restaurant \n",
"1 43.805630 -79.200378 Print Shop \n",
"2 43.782533 -79.163085 Bar \n",
"3 43.787919 -79.162977 Moving Target \n",
"4 43.767697 -79.189914 Pizza Place \n",
"5 43.765309 -79.191537 Electronics Store \n",
"6 43.766000 -79.191000 Spa \n",
"7 43.766299 -79.190720 Mexican Restaurant \n",
"8 43.764076 -79.193406 Rental Car Location \n",
"11 43.770037 -79.221156 Coffee Shop \n",
"12 43.770827 -79.223078 Coffee Shop \n",
"13 43.770812 -79.214502 Korean Restaurant \n",
"14 43.767585 -79.219570 Indian Restaurant \n",
"15 43.774697 -79.241142 Hakka Restaurant \n",
"16 43.775222 -79.241678 Caribbean Restaurant \n",
"17 43.774468 -79.241268 Thai Restaurant \n",
"18 43.774593 -79.236500 Athletics & Sports \n",
"19 43.774952 -79.241343 Bank \n",
"22 43.745089 -79.239336 Playground \n",
"23 43.744058 -79.244021 Grocery Store \n",
"24 43.743706 -79.244457 Cosmetics Shop \n",
"25 43.727447 -79.266240 Department Store \n",
"26 43.726895 -79.266157 Coffee Shop \n",
"27 43.727688 -79.266057 Chinese Restaurant \n",
"28 43.726904 -79.265886 Discount Store \n",
"29 43.732275 -79.262418 Train Station \n",
"32 43.710378 -79.290701 Fast Food Restaurant \n",
"33 43.712057 -79.281005 Intersection \n",
"34 43.711778 -79.279714 Bus Line \n",
"35 43.711229 -79.279602 Metro Station \n",
"36 43.711381 -79.279588 Bus Line \n",
"41 43.718256 -79.240135 Motel \n",
"42 43.717002 -79.242353 American Restaurant \n",
"43 43.691666 -79.264532 Café \n",
"44 43.695175 -79.262161 General Entertainment \n",
"45 43.694647 -79.262230 Skating Rink \n",
"46 43.695323 -79.261293 College Stadium \n",
"47 43.754768 -79.277199 Indian Restaurant \n",
"48 43.753833 -79.276611 Chinese Restaurant \n",
"49 43.754790 -79.277064 Latin American Restaurant \n",
"50 43.756042 -79.276276 Indian Restaurant \n",
"51 43.759279 -79.278325 Pet Store \n",
"56 43.746030 -79.293843 Breakfast Spot \n",
"57 43.746008 -79.293238 Sandwich Place \n",
"58 43.746701 -79.292896 Middle Eastern Restaurant \n",
"59 43.746136 -79.293782 Shopping Mall \n",
"60 43.751288 -79.301508 Auto Garage \n",
"62 43.792370 -79.260203 Breakfast Spot \n",
"63 43.791999 -79.258584 Lounge \n",
"64 43.792823 -79.259681 Sandwich Place \n",
"65 43.791179 -79.259714 Clothing Store \n",
"66 43.798496 -79.262196 Chinese Restaurant \n",
"67 43.778649 -79.308264 Italian Restaurant \n",
"68 43.780505 -79.298844 Chinese Restaurant \n",
"69 43.778234 -79.308299 Noodle House \n",
"70 43.780438 -79.299837 Thai Restaurant \n",
"71 43.780563 -79.298624 Pizza Place \n",
"76 43.815477 -79.289773 Park \n",
"77 43.815383 -79.289867 Playground \n",
"78 43.798879 -79.318335 Chinese Restaurant \n",
"79 43.798198 -79.318432 Chinese Restaurant \n",
"80 43.799445 -79.318563 Grocery Store \n",
"81 43.798983 -79.318838 Sandwich Place \n",
"82 43.798281 -79.318317 Coffee Shop "
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_venues.groupby('Neighborhood').head()"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 57 uniques categories.\n"
]
}
],
"source": [
"print('There are {} uniques categories.'.format(len(Scarborough_venues['Venue Category'].unique())))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Make one hot to to mechine learning"
]
},
{
"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>American Restaurant</th>\n",
" <th>Athletics &amp; Sports</th>\n",
" <th>Auto Garage</th>\n",
" <th>Bakery</th>\n",
" <th>Bank</th>\n",
" <th>Bar</th>\n",
" <th>Breakfast Spot</th>\n",
" <th>Brewery</th>\n",
" <th>Bus Line</th>\n",
" <th>Bus Station</th>\n",
" <th>Café</th>\n",
" <th>Camera Store</th>\n",
" <th>Caribbean Restaurant</th>\n",
" <th>Chinese Restaurant</th>\n",
" <th>Clothing Store</th>\n",
" <th>Coffee Shop</th>\n",
" <th>College Stadium</th>\n",
" <th>Cosmetics Shop</th>\n",
" <th>Department Store</th>\n",
" <th>Discount Store</th>\n",
" <th>Electronics Store</th>\n",
" <th>Fast Food Restaurant</th>\n",
" <th>Fried Chicken Joint</th>\n",
" <th>Furniture / Home Store</th>\n",
" <th>General Entertainment</th>\n",
" <th>Grocery Store</th>\n",
" <th>Hakka Restaurant</th>\n",
" <th>Indian Restaurant</th>\n",
" <th>Intersection</th>\n",
" <th>Italian Restaurant</th>\n",
" <th>Japanese Restaurant</th>\n",
" <th>Korean Restaurant</th>\n",
" <th>Latin American Restaurant</th>\n",
" <th>Lounge</th>\n",
" <th>Medical Center</th>\n",
" <th>Metro Station</th>\n",
" <th>Mexican Restaurant</th>\n",
" <th>Middle Eastern Restaurant</th>\n",
" <th>Motel</th>\n",
" <th>Moving Target</th>\n",
" <th>Noodle House</th>\n",
" <th>Park</th>\n",
" <th>Pet Store</th>\n",
" <th>Pharmacy</th>\n",
" <th>Pizza Place</th>\n",
" <th>Playground</th>\n",
" <th>Print Shop</th>\n",
" <th>Rental Car Location</th>\n",
" <th>Sandwich Place</th>\n",
" <th>Shopping Mall</th>\n",
" <th>Skating Rink</th>\n",
" <th>Soccer Field</th>\n",
" <th>Spa</th>\n",
" <th>Thai Restaurant</th>\n",
" <th>Thrift / Vintage Store</th>\n",
" <th>Train Station</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>RougeMalvern</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <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>RougeMalvern</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>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",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Highland CreekRouge HillPort Union</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <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>Highland CreekRouge HillPort Union</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>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",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>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",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood American Restaurant \\\n",
"0 RougeMalvern 0 \n",
"1 RougeMalvern 0 \n",
"2 Highland CreekRouge HillPort Union 0 \n",
"3 Highland CreekRouge HillPort Union 0 \n",
"4 GuildwoodMorningsideWest Hill 0 \n",
"\n",
" Athletics & Sports Auto Garage Bakery Bank Bar Breakfast Spot \\\n",
"0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 1 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
" Brewery Bus Line Bus Station Café Camera Store Caribbean Restaurant \\\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",
" Chinese Restaurant Clothing Store Coffee Shop College Stadium \\\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",
" Cosmetics Shop Department Store Discount Store Electronics 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",
" Fast Food Restaurant Fried Chicken Joint Furniture / Home Store \\\n",
"0 1 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" General Entertainment Grocery Store Hakka Restaurant Indian 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",
" Intersection Italian Restaurant Japanese Restaurant Korean 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",
" Latin American Restaurant Lounge Medical Center Metro Station \\\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",
" Mexican Restaurant Middle Eastern Restaurant Motel Moving Target \\\n",
"0 0 0 0 0 \n",
"1 0 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 1 \n",
"4 0 0 0 0 \n",
"\n",
" Noodle House Park Pet Store Pharmacy Pizza Place 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 1 0 \n",
"\n",
" Print Shop Rental Car Location Sandwich Place Shopping Mall \\\n",
"0 0 0 0 0 \n",
"1 1 0 0 0 \n",
"2 0 0 0 0 \n",
"3 0 0 0 0 \n",
"4 0 0 0 0 \n",
"\n",
" Skating Rink Soccer Field Spa Thai Restaurant Thrift / Vintage 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 0 0 0 0 0 \n",
"\n",
" Train Station Vietnamese Restaurant \n",
"0 0 0 \n",
"1 0 0 \n",
"2 0 0 \n",
"3 0 0 \n",
"4 0 0 "
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# one hot encoding\n",
"Scarborough_onehot = pd.get_dummies(Scarborough_venues[['Venue Category']], prefix=\"\", prefix_sep=\"\")\n",
"# add neighborhood column back to dataframe\n",
"Scarborough_onehot['Neighborhood'] = Scarborough_venues['Neighborhood'] \n",
"# move neighborhood column to the first column\n",
"fixed_columns = [Scarborough_onehot.columns[-1]] + list(Scarborough_onehot.columns[:-1])\n",
"Scarborough_onehot = Scarborough_onehot[fixed_columns]\n",
"Scarborough_onehot.head()"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(92, 58)"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_onehot.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Group by Neigbourhood"
]
},
{
"cell_type": "code",
"execution_count": 40,
"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>American Restaurant</th>\n",
" <th>Athletics &amp; Sports</th>\n",
" <th>Auto Garage</th>\n",
" <th>Bakery</th>\n",
" <th>Bank</th>\n",
" <th>Bar</th>\n",
" <th>Breakfast Spot</th>\n",
" <th>Brewery</th>\n",
" <th>Bus Line</th>\n",
" <th>Bus Station</th>\n",
" <th>Café</th>\n",
" <th>Camera Store</th>\n",
" <th>Caribbean Restaurant</th>\n",
" <th>Chinese Restaurant</th>\n",
" <th>Clothing Store</th>\n",
" <th>Coffee Shop</th>\n",
" <th>College Stadium</th>\n",
" <th>Cosmetics Shop</th>\n",
" <th>Department Store</th>\n",
" <th>Discount Store</th>\n",
" <th>Electronics Store</th>\n",
" <th>Fast Food Restaurant</th>\n",
" <th>Fried Chicken Joint</th>\n",
" <th>Furniture / Home Store</th>\n",
" <th>General Entertainment</th>\n",
" <th>Grocery Store</th>\n",
" <th>Hakka Restaurant</th>\n",
" <th>Indian Restaurant</th>\n",
" <th>Intersection</th>\n",
" <th>Italian Restaurant</th>\n",
" <th>Japanese Restaurant</th>\n",
" <th>Korean Restaurant</th>\n",
" <th>Latin American Restaurant</th>\n",
" <th>Lounge</th>\n",
" <th>Medical Center</th>\n",
" <th>Metro Station</th>\n",
" <th>Mexican Restaurant</th>\n",
" <th>Middle Eastern Restaurant</th>\n",
" <th>Motel</th>\n",
" <th>Moving Target</th>\n",
" <th>Noodle House</th>\n",
" <th>Park</th>\n",
" <th>Pet Store</th>\n",
" <th>Pharmacy</th>\n",
" <th>Pizza Place</th>\n",
" <th>Playground</th>\n",
" <th>Print Shop</th>\n",
" <th>Rental Car Location</th>\n",
" <th>Sandwich Place</th>\n",
" <th>Shopping Mall</th>\n",
" <th>Skating Rink</th>\n",
" <th>Soccer Field</th>\n",
" <th>Spa</th>\n",
" <th>Thai Restaurant</th>\n",
" <th>Thrift / Vintage Store</th>\n",
" <th>Train Station</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Agincourt</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.200000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.200000</td>\n",
" <td>0.2</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.2</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.200000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.5</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.500000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.25</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.25</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.25</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.25</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Cedarbrae</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.142857</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.222222</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.222222</td>\n",
" <td>0.111111</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.111111</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.222222</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>0.5</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.5</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.222222</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.111111</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" <td>0.000000</td>\n",
" <td>0.111111</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.285714</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.5</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.5</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.0</td>\n",
" <td>0.142857</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.142857</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.071429</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.071429</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.071429</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.166667</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.166667</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.333333</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.166667</td>\n",
" <td>0.166667</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>RougeMalvern</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.500000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.5</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Scarborough Village</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.333333</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.333333</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.333333</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Woburn</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.500000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.250000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.25</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood American Restaurant \\\n",
"0 Agincourt 0.0 \n",
"1 Agincourt NorthL'Amoreaux EastMillikenSteeles ... 0.0 \n",
"2 Birch CliffCliffside West 0.0 \n",
"3 Cedarbrae 0.0 \n",
"4 ClairleaGolden MileOakridge 0.0 \n",
"5 Clarks CornersSullivanTam O'Shanter 0.0 \n",
"6 CliffcrestCliffsideScarborough Village West 0.5 \n",
"7 Dorset ParkScarborough Town CentreWexford Heights 0.0 \n",
"8 East Birchmount ParkIonviewKennedy Park 0.0 \n",
"9 GuildwoodMorningsideWest Hill 0.0 \n",
"10 Highland CreekRouge HillPort Union 0.0 \n",
"11 L'Amoreaux WestSteeles West 0.0 \n",
"12 MaryvaleWexford 0.0 \n",
"13 RougeMalvern 0.0 \n",
"14 Scarborough Village 0.0 \n",
"15 Woburn 0.0 \n",
"\n",
" Athletics & Sports Auto Garage Bakery Bank Bar Breakfast Spot \\\n",
"0 0.000000 0.000000 0.000000 0.000000 0.0 0.200000 \n",
"1 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"2 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"3 0.142857 0.000000 0.142857 0.142857 0.0 0.000000 \n",
"4 0.000000 0.000000 0.222222 0.000000 0.0 0.000000 \n",
"5 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"6 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"7 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"8 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"9 0.000000 0.000000 0.000000 0.000000 0.0 0.142857 \n",
"10 0.000000 0.000000 0.000000 0.000000 0.5 0.000000 \n",
"11 0.000000 0.000000 0.000000 0.000000 0.0 0.071429 \n",
"12 0.000000 0.166667 0.000000 0.000000 0.0 0.166667 \n",
"13 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"14 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"15 0.000000 0.000000 0.000000 0.000000 0.0 0.000000 \n",
"\n",
" Brewery Bus Line Bus Station Café Camera Store Caribbean Restaurant \\\n",
"0 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"1 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"2 0.000000 0.000000 0.000000 0.25 0.000000 0.000000 \n",
"3 0.000000 0.000000 0.000000 0.00 0.000000 0.142857 \n",
"4 0.000000 0.222222 0.111111 0.00 0.000000 0.000000 \n",
"5 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"6 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"7 0.111111 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"8 0.000000 0.000000 0.142857 0.00 0.000000 0.000000 \n",
"9 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"10 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"11 0.000000 0.000000 0.000000 0.00 0.071429 0.000000 \n",
"12 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"13 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"14 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"15 0.000000 0.000000 0.000000 0.00 0.000000 0.000000 \n",
"\n",
" Chinese Restaurant Clothing Store Coffee Shop College Stadium \\\n",
"0 0.200000 0.2 0.000000 0.00 \n",
"1 0.000000 0.0 0.000000 0.00 \n",
"2 0.000000 0.0 0.000000 0.25 \n",
"3 0.000000 0.0 0.000000 0.00 \n",
"4 0.000000 0.0 0.000000 0.00 \n",
"5 0.111111 0.0 0.000000 0.00 \n",
"6 0.000000 0.0 0.000000 0.00 \n",
"7 0.111111 0.0 0.000000 0.00 \n",
"8 0.142857 0.0 0.142857 0.00 \n",
"9 0.000000 0.0 0.000000 0.00 \n",
"10 0.000000 0.0 0.000000 0.00 \n",
"11 0.142857 0.0 0.142857 0.00 \n",
"12 0.000000 0.0 0.000000 0.00 \n",
"13 0.000000 0.0 0.000000 0.00 \n",
"14 0.000000 0.0 0.000000 0.00 \n",
"15 0.000000 0.0 0.500000 0.00 \n",
"\n",
" Cosmetics Shop Department Store Discount Store Electronics Store \\\n",
"0 0.000000 0.000000 0.000000 0.000000 \n",
"1 0.000000 0.000000 0.000000 0.000000 \n",
"2 0.000000 0.000000 0.000000 0.000000 \n",
"3 0.000000 0.000000 0.000000 0.000000 \n",
"4 0.000000 0.000000 0.000000 0.000000 \n",
"5 0.000000 0.000000 0.000000 0.000000 \n",
"6 0.000000 0.000000 0.000000 0.000000 \n",
"7 0.000000 0.000000 0.000000 0.000000 \n",
"8 0.000000 0.142857 0.285714 0.000000 \n",
"9 0.000000 0.000000 0.000000 0.142857 \n",
"10 0.000000 0.000000 0.000000 0.000000 \n",
"11 0.000000 0.000000 0.000000 0.000000 \n",
"12 0.000000 0.000000 0.000000 0.000000 \n",
"13 0.000000 0.000000 0.000000 0.000000 \n",
"14 0.333333 0.000000 0.000000 0.000000 \n",
"15 0.000000 0.000000 0.000000 0.000000 \n",
"\n",
" Fast Food Restaurant Fried Chicken Joint Furniture / Home Store \\\n",
"0 0.000000 0.000000 0.000000 \n",
"1 0.000000 0.000000 0.000000 \n",
"2 0.000000 0.000000 0.000000 \n",
"3 0.000000 0.142857 0.000000 \n",
"4 0.111111 0.000000 0.000000 \n",
"5 0.111111 0.111111 0.000000 \n",
"6 0.000000 0.000000 0.000000 \n",
"7 0.000000 0.000000 0.111111 \n",
"8 0.000000 0.000000 0.000000 \n",
"9 0.000000 0.000000 0.000000 \n",
"10 0.000000 0.000000 0.000000 \n",
"11 0.142857 0.000000 0.000000 \n",
"12 0.000000 0.000000 0.000000 \n",
"13 0.500000 0.000000 0.000000 \n",
"14 0.000000 0.000000 0.000000 \n",
"15 0.000000 0.000000 0.000000 \n",
"\n",
" General Entertainment Grocery Store Hakka Restaurant Indian Restaurant \\\n",
"0 0.00 0.000000 0.000000 0.000000 \n",
"1 0.00 0.000000 0.000000 0.000000 \n",
"2 0.25 0.000000 0.000000 0.000000 \n",
"3 0.00 0.000000 0.142857 0.000000 \n",
"4 0.00 0.000000 0.000000 0.000000 \n",
"5 0.00 0.000000 0.000000 0.000000 \n",
"6 0.00 0.000000 0.000000 0.000000 \n",
"7 0.00 0.000000 0.000000 0.222222 \n",
"8 0.00 0.000000 0.000000 0.000000 \n",
"9 0.00 0.000000 0.000000 0.000000 \n",
"10 0.00 0.000000 0.000000 0.000000 \n",
"11 0.00 0.071429 0.000000 0.071429 \n",
"12 0.00 0.000000 0.000000 0.000000 \n",
"13 0.00 0.000000 0.000000 0.000000 \n",
"14 0.00 0.333333 0.000000 0.000000 \n",
"15 0.00 0.000000 0.000000 0.250000 \n",
"\n",
" Intersection Italian Restaurant Japanese Restaurant Korean Restaurant \\\n",
"0 0.000000 0.000000 0.000000 0.00 \n",
"1 0.000000 0.000000 0.000000 0.00 \n",
"2 0.000000 0.000000 0.000000 0.00 \n",
"3 0.000000 0.000000 0.000000 0.00 \n",
"4 0.111111 0.000000 0.000000 0.00 \n",
"5 0.000000 0.111111 0.000000 0.00 \n",
"6 0.000000 0.000000 0.000000 0.00 \n",
"7 0.000000 0.000000 0.000000 0.00 \n",
"8 0.000000 0.000000 0.000000 0.00 \n",
"9 0.000000 0.000000 0.000000 0.00 \n",
"10 0.000000 0.000000 0.000000 0.00 \n",
"11 0.000000 0.000000 0.071429 0.00 \n",
"12 0.000000 0.000000 0.000000 0.00 \n",
"13 0.000000 0.000000 0.000000 0.00 \n",
"14 0.000000 0.000000 0.000000 0.00 \n",
"15 0.000000 0.000000 0.000000 0.25 \n",
"\n",
" Latin American Restaurant Lounge Medical Center Metro Station \\\n",
"0 0.000000 0.2 0.000000 0.000000 \n",
"1 0.000000 0.0 0.000000 0.000000 \n",
"2 0.000000 0.0 0.000000 0.000000 \n",
"3 0.000000 0.0 0.000000 0.000000 \n",
"4 0.000000 0.0 0.000000 0.111111 \n",
"5 0.000000 0.0 0.000000 0.000000 \n",
"6 0.000000 0.0 0.000000 0.000000 \n",
"7 0.111111 0.0 0.000000 0.000000 \n",
"8 0.000000 0.0 0.000000 0.000000 \n",
"9 0.000000 0.0 0.142857 0.000000 \n",
"10 0.000000 0.0 0.000000 0.000000 \n",
"11 0.000000 0.0 0.000000 0.000000 \n",
"12 0.000000 0.0 0.000000 0.000000 \n",
"13 0.000000 0.0 0.000000 0.000000 \n",
"14 0.000000 0.0 0.000000 0.000000 \n",
"15 0.000000 0.0 0.000000 0.000000 \n",
"\n",
" Mexican Restaurant Middle Eastern Restaurant Motel Moving Target \\\n",
"0 0.000000 0.000000 0.0 0.0 \n",
"1 0.000000 0.000000 0.0 0.0 \n",
"2 0.000000 0.000000 0.0 0.0 \n",
"3 0.000000 0.000000 0.0 0.0 \n",
"4 0.000000 0.000000 0.0 0.0 \n",
"5 0.000000 0.000000 0.0 0.0 \n",
"6 0.000000 0.000000 0.5 0.0 \n",
"7 0.000000 0.000000 0.0 0.0 \n",
"8 0.000000 0.000000 0.0 0.0 \n",
"9 0.142857 0.000000 0.0 0.0 \n",
"10 0.000000 0.000000 0.0 0.5 \n",
"11 0.000000 0.000000 0.0 0.0 \n",
"12 0.000000 0.333333 0.0 0.0 \n",
"13 0.000000 0.000000 0.0 0.0 \n",
"14 0.000000 0.000000 0.0 0.0 \n",
"15 0.000000 0.000000 0.0 0.0 \n",
"\n",
" Noodle House Park Pet Store Pharmacy Pizza Place Playground \\\n",
"0 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"1 0.000000 0.5 0.000000 0.000000 0.000000 0.500000 \n",
"2 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"3 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"4 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"5 0.111111 0.0 0.000000 0.000000 0.222222 0.000000 \n",
"6 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"7 0.000000 0.0 0.111111 0.000000 0.000000 0.000000 \n",
"8 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"9 0.000000 0.0 0.000000 0.000000 0.142857 0.000000 \n",
"10 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"11 0.000000 0.0 0.000000 0.071429 0.071429 0.000000 \n",
"12 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"13 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"14 0.000000 0.0 0.000000 0.000000 0.000000 0.333333 \n",
"15 0.000000 0.0 0.000000 0.000000 0.000000 0.000000 \n",
"\n",
" Print Shop Rental Car Location Sandwich Place Shopping Mall \\\n",
"0 0.0 0.000000 0.200000 0.000000 \n",
"1 0.0 0.000000 0.000000 0.000000 \n",
"2 0.0 0.000000 0.000000 0.000000 \n",
"3 0.0 0.000000 0.000000 0.000000 \n",
"4 0.0 0.000000 0.000000 0.000000 \n",
"5 0.0 0.000000 0.000000 0.111111 \n",
"6 0.0 0.000000 0.000000 0.000000 \n",
"7 0.0 0.000000 0.000000 0.000000 \n",
"8 0.0 0.000000 0.000000 0.000000 \n",
"9 0.0 0.142857 0.000000 0.000000 \n",
"10 0.0 0.000000 0.000000 0.000000 \n",
"11 0.0 0.000000 0.071429 0.000000 \n",
"12 0.0 0.000000 0.166667 0.166667 \n",
"13 0.5 0.000000 0.000000 0.000000 \n",
"14 0.0 0.000000 0.000000 0.000000 \n",
"15 0.0 0.000000 0.000000 0.000000 \n",
"\n",
" Skating Rink Soccer Field Spa Thai Restaurant \\\n",
"0 0.00 0.000000 0.000000 0.000000 \n",
"1 0.00 0.000000 0.000000 0.000000 \n",
"2 0.25 0.000000 0.000000 0.000000 \n",
"3 0.00 0.000000 0.000000 0.142857 \n",
"4 0.00 0.111111 0.000000 0.000000 \n",
"5 0.00 0.000000 0.000000 0.111111 \n",
"6 0.00 0.000000 0.000000 0.000000 \n",
"7 0.00 0.000000 0.000000 0.000000 \n",
"8 0.00 0.000000 0.000000 0.000000 \n",
"9 0.00 0.000000 0.142857 0.000000 \n",
"10 0.00 0.000000 0.000000 0.000000 \n",
"11 0.00 0.000000 0.000000 0.000000 \n",
"12 0.00 0.000000 0.000000 0.000000 \n",
"13 0.00 0.000000 0.000000 0.000000 \n",
"14 0.00 0.000000 0.000000 0.000000 \n",
"15 0.00 0.000000 0.000000 0.000000 \n",
"\n",
" Thrift / Vintage Store Train Station Vietnamese Restaurant \n",
"0 0.000000 0.000000 0.000000 \n",
"1 0.000000 0.000000 0.000000 \n",
"2 0.000000 0.000000 0.000000 \n",
"3 0.000000 0.000000 0.000000 \n",
"4 0.000000 0.000000 0.000000 \n",
"5 0.000000 0.000000 0.000000 \n",
"6 0.000000 0.000000 0.000000 \n",
"7 0.111111 0.000000 0.111111 \n",
"8 0.000000 0.142857 0.000000 \n",
"9 0.000000 0.000000 0.000000 \n",
"10 0.000000 0.000000 0.000000 \n",
"11 0.000000 0.000000 0.000000 \n",
"12 0.000000 0.000000 0.000000 \n",
"13 0.000000 0.000000 0.000000 \n",
"14 0.000000 0.000000 0.000000 \n",
"15 0.000000 0.000000 0.000000 "
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_grouped = Scarborough_onehot.groupby('Neighborhood').mean().reset_index()\n",
"Scarborough_grouped"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(16, 58)"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_grouped.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Review the top 5 venues"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"----Agincourt----\n",
" venue freq\n",
"0 Sandwich Place 0.2\n",
"1 Lounge 0.2\n",
"2 Clothing Store 0.2\n",
"3 Chinese Restaurant 0.2\n",
"4 Breakfast Spot 0.2\n",
"\n",
"\n",
"----Agincourt NorthL'Amoreaux EastMillikenSteeles East----\n",
" venue freq\n",
"0 Playground 0.5\n",
"1 Park 0.5\n",
"2 American Restaurant 0.0\n",
"3 Pet Store 0.0\n",
"4 Korean Restaurant 0.0\n",
"\n",
"\n",
"----Birch CliffCliffside West----\n",
" venue freq\n",
"0 College Stadium 0.25\n",
"1 General Entertainment 0.25\n",
"2 Skating Rink 0.25\n",
"3 Café 0.25\n",
"4 American Restaurant 0.00\n",
"\n",
"\n",
"----Cedarbrae----\n",
" venue freq\n",
"0 Hakka Restaurant 0.14\n",
"1 Bakery 0.14\n",
"2 Bank 0.14\n",
"3 Athletics & Sports 0.14\n",
"4 Thai Restaurant 0.14\n",
"\n",
"\n",
"----ClairleaGolden MileOakridge----\n",
" venue freq\n",
"0 Bus Line 0.22\n",
"1 Bakery 0.22\n",
"2 Soccer Field 0.11\n",
"3 Fast Food Restaurant 0.11\n",
"4 Bus Station 0.11\n",
"\n",
"\n",
"----Clarks CornersSullivanTam O'Shanter----\n",
" venue freq\n",
"0 Pizza Place 0.22\n",
"1 Italian Restaurant 0.11\n",
"2 Fried Chicken Joint 0.11\n",
"3 Chinese Restaurant 0.11\n",
"4 Fast Food Restaurant 0.11\n",
"\n",
"\n",
"----CliffcrestCliffsideScarborough Village West----\n",
" venue freq\n",
"0 American Restaurant 0.5\n",
"1 Motel 0.5\n",
"2 Italian Restaurant 0.0\n",
"3 Korean Restaurant 0.0\n",
"4 Latin American Restaurant 0.0\n",
"\n",
"\n",
"----Dorset ParkScarborough Town CentreWexford Heights----\n",
" venue freq\n",
"0 Indian Restaurant 0.22\n",
"1 Vietnamese Restaurant 0.11\n",
"2 Brewery 0.11\n",
"3 Furniture / Home Store 0.11\n",
"4 Pet Store 0.11\n",
"\n",
"\n",
"----East Birchmount ParkIonviewKennedy Park----\n",
" venue freq\n",
"0 Discount Store 0.29\n",
"1 Coffee Shop 0.14\n",
"2 Bus Station 0.14\n",
"3 Chinese Restaurant 0.14\n",
"4 Department Store 0.14\n",
"\n",
"\n",
"----GuildwoodMorningsideWest Hill----\n",
" venue freq\n",
"0 Pizza Place 0.14\n",
"1 Medical Center 0.14\n",
"2 Spa 0.14\n",
"3 Breakfast Spot 0.14\n",
"4 Mexican Restaurant 0.14\n",
"\n",
"\n",
"----Highland CreekRouge HillPort Union----\n",
" venue freq\n",
"0 Bar 0.5\n",
"1 Moving Target 0.5\n",
"2 American Restaurant 0.0\n",
"3 Pharmacy 0.0\n",
"4 Korean Restaurant 0.0\n",
"\n",
"\n",
"----L'Amoreaux WestSteeles West----\n",
" venue freq\n",
"0 Chinese Restaurant 0.14\n",
"1 Fast Food Restaurant 0.14\n",
"2 Coffee Shop 0.14\n",
"3 Pharmacy 0.07\n",
"4 Japanese Restaurant 0.07\n",
"\n",
"\n",
"----MaryvaleWexford----\n",
" venue freq\n",
"0 Middle Eastern Restaurant 0.33\n",
"1 Auto Garage 0.17\n",
"2 Breakfast Spot 0.17\n",
"3 Shopping Mall 0.17\n",
"4 Sandwich Place 0.17\n",
"\n",
"\n",
"----RougeMalvern----\n",
" venue freq\n",
"0 Fast Food Restaurant 0.5\n",
"1 Print Shop 0.5\n",
"2 American Restaurant 0.0\n",
"3 Pet Store 0.0\n",
"4 Korean Restaurant 0.0\n",
"\n",
"\n",
"----Scarborough Village----\n",
" venue freq\n",
"0 Grocery Store 0.33\n",
"1 Playground 0.33\n",
"2 Cosmetics Shop 0.33\n",
"3 American Restaurant 0.00\n",
"4 Pet Store 0.00\n",
"\n",
"\n",
"----Woburn----\n",
" venue freq\n",
"0 Coffee Shop 0.50\n",
"1 Korean Restaurant 0.25\n",
"2 Indian Restaurant 0.25\n",
"3 Latin American Restaurant 0.00\n",
"4 Lounge 0.00\n",
"\n",
"\n"
]
}
],
"source": [
"num_top_venues = 5\n",
"for hood in Scarborough_grouped['Neighborhood']:\n",
" print(\"----\"+hood+\"----\")\n",
" temp = Scarborough_grouped[Scarborough_grouped['Neighborhood'] == hood].T.reset_index()\n",
" temp.columns = ['venue','freq']\n",
" temp = temp.iloc[1:]\n",
" temp['freq'] = temp['freq'].astype(float)\n",
" temp = temp.round({'freq': 2})\n",
" print(temp.sort_values('freq', ascending=False).reset_index(drop=True).head(num_top_venues))\n",
" print('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Function to sort the most common venues"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"def return_most_common_venues(row, num_top_venues):\n",
" row_categories = row.iloc[1:]\n",
" row_categories_sorted = row_categories.sort_values(ascending=False) \n",
" return row_categories_sorted.index.values[0:num_top_venues]"
]
},
{
"cell_type": "code",
"execution_count": 44,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Agincourt</td>\n",
" <td>Clothing Store</td>\n",
" <td>Lounge</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Agincourt NorthL'Amoreaux EastMillikenSteeles ...</td>\n",
" <td>Park</td>\n",
" <td>Playground</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" <td>Department Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Birch CliffCliffside West</td>\n",
" <td>General Entertainment</td>\n",
" <td>Skating Rink</td>\n",
" <td>Café</td>\n",
" <td>College Stadium</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Cedarbrae</td>\n",
" <td>Caribbean Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Bank</td>\n",
" <td>Hakka Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Athletics &amp; Sports</td>\n",
" <td>Auto Garage</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>ClairleaGolden MileOakridge</td>\n",
" <td>Bakery</td>\n",
" <td>Bus Line</td>\n",
" <td>Intersection</td>\n",
" <td>Soccer Field</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Bus Station</td>\n",
" <td>Metro Station</td>\n",
" <td>Coffee Shop</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Clarks CornersSullivanTam O'Shanter</td>\n",
" <td>Pizza Place</td>\n",
" <td>Noodle House</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Shopping Mall</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>CliffcrestCliffsideScarborough Village West</td>\n",
" <td>American Restaurant</td>\n",
" <td>Motel</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Dorset ParkScarborough Town CentreWexford Heights</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Brewery</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Latin American Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Pet Store</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Thrift / Vintage Store</td>\n",
" <td>Bar</td>\n",
" <td>College Stadium</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>East Birchmount ParkIonviewKennedy Park</td>\n",
" <td>Discount Store</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Bus Station</td>\n",
" <td>Department Store</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Train Station</td>\n",
" <td>Bar</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Hakka Restaurant</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Mexican Restaurant</td>\n",
" <td>Spa</td>\n",
" <td>Medical Center</td>\n",
" <td>Electronics Store</td>\n",
" <td>Pizza Place</td>\n",
" <td>Rental Car Location</td>\n",
" <td>Department Store</td>\n",
" <td>College Stadium</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>Bar</td>\n",
" <td>Moving Target</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>L'Amoreaux WestSteeles West</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Grocery Store</td>\n",
" <td>Pharmacy</td>\n",
" <td>Pizza Place</td>\n",
" <td>Camera Store</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>MaryvaleWexford</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Auto Garage</td>\n",
" <td>Shopping Mall</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Electronics Store</td>\n",
" <td>College Stadium</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Department Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>RougeMalvern</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Print Shop</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Scarborough Village</td>\n",
" <td>Grocery Store</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Playground</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Woburn</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Korean Restaurant</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood \\\n",
"0 Agincourt \n",
"1 Agincourt NorthL'Amoreaux EastMillikenSteeles ... \n",
"2 Birch CliffCliffside West \n",
"3 Cedarbrae \n",
"4 ClairleaGolden MileOakridge \n",
"5 Clarks CornersSullivanTam O'Shanter \n",
"6 CliffcrestCliffsideScarborough Village West \n",
"7 Dorset ParkScarborough Town CentreWexford Heights \n",
"8 East Birchmount ParkIonviewKennedy Park \n",
"9 GuildwoodMorningsideWest Hill \n",
"10 Highland CreekRouge HillPort Union \n",
"11 L'Amoreaux WestSteeles West \n",
"12 MaryvaleWexford \n",
"13 RougeMalvern \n",
"14 Scarborough Village \n",
"15 Woburn \n",
"\n",
" 1st Most Common Venue 2nd Most Common Venue 3rd Most Common Venue \\\n",
"0 Clothing Store Lounge Breakfast Spot \n",
"1 Park Playground Vietnamese Restaurant \n",
"2 General Entertainment Skating Rink Café \n",
"3 Caribbean Restaurant Bakery Fried Chicken Joint \n",
"4 Bakery Bus Line Intersection \n",
"5 Pizza Place Noodle House Thai Restaurant \n",
"6 American Restaurant Motel Clothing Store \n",
"7 Indian Restaurant Brewery Furniture / Home Store \n",
"8 Discount Store Chinese Restaurant Bus Station \n",
"9 Breakfast Spot Mexican Restaurant Spa \n",
"10 Bar Moving Target Vietnamese Restaurant \n",
"11 Chinese Restaurant Coffee Shop Fast Food Restaurant \n",
"12 Middle Eastern Restaurant Sandwich Place Auto Garage \n",
"13 Fast Food Restaurant Print Shop Vietnamese Restaurant \n",
"14 Grocery Store Cosmetics Shop Playground \n",
"15 Coffee Shop Korean Restaurant Indian Restaurant \n",
"\n",
" 4th Most Common Venue 5th Most Common Venue 6th Most Common Venue \\\n",
"0 Sandwich Place Chinese Restaurant Vietnamese Restaurant \n",
"1 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"2 College Stadium Vietnamese Restaurant Clothing Store \n",
"3 Bank Hakka Restaurant Thai Restaurant \n",
"4 Soccer Field Fast Food Restaurant Bus Station \n",
"5 Fried Chicken Joint Italian Restaurant Fast Food Restaurant \n",
"6 Grocery Store General Entertainment Furniture / Home Store \n",
"7 Latin American Restaurant Chinese Restaurant Pet Store \n",
"8 Department Store Coffee Shop Train Station \n",
"9 Medical Center Electronics Store Pizza Place \n",
"10 Clothing Store Grocery Store General Entertainment \n",
"11 Sandwich Place Grocery Store Pharmacy \n",
"12 Shopping Mall Breakfast Spot Electronics Store \n",
"13 Chinese Restaurant Grocery Store General Entertainment \n",
"14 Vietnamese Restaurant Chinese Restaurant General Entertainment \n",
"15 Vietnamese Restaurant Clothing Store Grocery Store \n",
"\n",
" 7th Most Common Venue 8th Most Common Venue 9th Most Common Venue \\\n",
"0 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"1 Fast Food Restaurant Electronics Store Discount Store \n",
"2 Grocery Store Furniture / Home Store Fried Chicken Joint \n",
"3 Athletics & Sports Auto Garage Grocery Store \n",
"4 Metro Station Coffee Shop General Entertainment \n",
"5 Shopping Mall Chinese Restaurant Clothing Store \n",
"6 Fried Chicken Joint Fast Food Restaurant Electronics Store \n",
"7 Vietnamese Restaurant Thrift / Vintage Store Bar \n",
"8 Bar Cosmetics Shop Hakka Restaurant \n",
"9 Rental Car Location Department Store College Stadium \n",
"10 Furniture / Home Store Fried Chicken Joint Fast Food Restaurant \n",
"11 Pizza Place Camera Store Breakfast Spot \n",
"12 College Stadium Cosmetics Shop Department Store \n",
"13 Furniture / Home Store Fried Chicken Joint Electronics Store \n",
"14 Furniture / Home Store Fried Chicken Joint Fast Food Restaurant \n",
"15 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"\n",
" 10th Most Common Venue \n",
"0 Fast Food Restaurant \n",
"1 Department Store \n",
"2 Fast Food Restaurant \n",
"3 General Entertainment \n",
"4 Furniture / Home Store \n",
"5 Coffee Shop \n",
"6 Discount Store \n",
"7 College Stadium \n",
"8 Grocery Store \n",
"9 Cosmetics Shop \n",
"10 Electronics Store \n",
"11 Japanese Restaurant \n",
"12 Discount Store \n",
"13 Discount Store \n",
"14 Electronics Store \n",
"15 Fast Food Restaurant "
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"num_top_venues = 10\n",
"\n",
"indicators = ['st', 'nd', 'rd']\n",
"# create columns according to number of top venues\n",
"columns = ['Neighborhood']\n",
"for ind in np.arange(num_top_venues):\n",
" try:\n",
" columns.append('{}{} Most Common Venue'.format(ind+1, indicators[ind]))\n",
" except:\n",
" columns.append('{}th Most Common Venue'.format(ind+1))\n",
"# create a new dataframe\n",
"neighborhoods_venues_sorted = pd.DataFrame(columns=columns)\n",
"neighborhoods_venues_sorted['Neighborhood'] = Scarborough_grouped['Neighborhood']\n",
"\n",
"for ind in np.arange(Scarborough_grouped.shape[0]):\n",
" neighborhoods_venues_sorted.iloc[ind, 1:] = return_most_common_venues(Scarborough_grouped.iloc[ind, :], num_top_venues)\n",
"\n",
"neighborhoods_venues_sorted"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cluster the venus using K means"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0, 0, 0, 0, 0, 0, 2, 0, 0, 0], dtype=int32)"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# set number of clusters\n",
"kclusters = 3\n",
"Scarborough_grouped_clustering = Scarborough_grouped.drop('Neighborhood', 1)\n",
"# run k-means clustering\n",
"kmeans = KMeans(n_clusters=kclusters, random_state=0).fit(Scarborough_grouped_clustering)\n",
"# check cluster labels generated for each row in the dataframe\n",
"kmeans.labels_[0:10]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Make labels"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"Scarborough_merged = Scarborough_data\n",
"\n",
"# add clustering labels\n",
"Scarborough_merged['Cluster Labels'] = kmeans.labels_\n",
"# make the column name the same\n",
"Scarborough_merged.rename(columns={'Neighbourhood':'Neighborhood'}, inplace = True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Merge neighborhoods_venues_sorted to Scarborough_merged by column \"Neighborhood\""
]
},
{
"cell_type": "code",
"execution_count": 47,
"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>Postcode</th>\n",
" <th>Borough</th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Labels</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>M1B</td>\n",
" <td>Scarborough</td>\n",
" <td>RougeMalvern</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>0</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Print Shop</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>M1C</td>\n",
" <td>Scarborough</td>\n",
" <td>Highland CreekRouge HillPort Union</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>0</td>\n",
" <td>Bar</td>\n",
" <td>Moving Target</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>M1E</td>\n",
" <td>Scarborough</td>\n",
" <td>GuildwoodMorningsideWest Hill</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>0</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Mexican Restaurant</td>\n",
" <td>Spa</td>\n",
" <td>Medical Center</td>\n",
" <td>Electronics Store</td>\n",
" <td>Pizza Place</td>\n",
" <td>Rental Car Location</td>\n",
" <td>Department Store</td>\n",
" <td>College Stadium</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>M1G</td>\n",
" <td>Scarborough</td>\n",
" <td>Woburn</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>0</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Korean Restaurant</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>M1H</td>\n",
" <td>Scarborough</td>\n",
" <td>Cedarbrae</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>0</td>\n",
" <td>Caribbean Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Bank</td>\n",
" <td>Hakka Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Athletics &amp; Sports</td>\n",
" <td>Auto Garage</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Postcode Borough Neighborhood Latitude \\\n",
"0 M1B Scarborough RougeMalvern 43.806686 \n",
"1 M1C Scarborough Highland CreekRouge HillPort Union 43.784535 \n",
"2 M1E Scarborough GuildwoodMorningsideWest Hill 43.763573 \n",
"3 M1G Scarborough Woburn 43.770992 \n",
"4 M1H Scarborough Cedarbrae 43.773136 \n",
"\n",
" Longitude Cluster Labels 1st Most Common Venue 2nd Most Common Venue \\\n",
"0 -79.194353 0 Fast Food Restaurant Print Shop \n",
"1 -79.160497 0 Bar Moving Target \n",
"2 -79.188711 0 Breakfast Spot Mexican Restaurant \n",
"3 -79.216917 0 Coffee Shop Korean Restaurant \n",
"4 -79.239476 0 Caribbean Restaurant Bakery \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"0 Vietnamese Restaurant Chinese Restaurant Grocery Store \n",
"1 Vietnamese Restaurant Clothing Store Grocery Store \n",
"2 Spa Medical Center Electronics Store \n",
"3 Indian Restaurant Vietnamese Restaurant Clothing Store \n",
"4 Fried Chicken Joint Bank Hakka Restaurant \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"0 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"1 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"2 Pizza Place Rental Car Location Department Store \n",
"3 Grocery Store General Entertainment Furniture / Home Store \n",
"4 Thai Restaurant Athletics & Sports Auto Garage \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"0 Electronics Store Discount Store \n",
"1 Fast Food Restaurant Electronics Store \n",
"2 College Stadium Cosmetics Shop \n",
"3 Fried Chicken Joint Fast Food Restaurant \n",
"4 Grocery Store General Entertainment "
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# merge toronto_grouped with toronto_data to add latitude/longitude for each neighborhood\n",
"Scarborough_merged = Scarborough_merged.join(neighborhoods_venues_sorted.set_index('Neighborhood'), on='Neighborhood')\n",
"\n",
"Scarborough_merged.head() # check the last columns!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Map the Clusters"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDMuNzczMDc3LC03OS4yNTc3NzRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyXzM0ZTdhMmJhY2VhMTQxYTU5NWUwZTAzZDg0Y2RjMjllID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMGZiNDY4ZTg2NjA0Njc4OGExMjYwODJjNDI2NmJmNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwNjY4NjI5OTk5OTk5NiwtNzkuMTk0MzUzNDAwMDAwMDFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODQ5ZjE4MGJmM2E1NGNjOGEwMjk2NjE4NzBkZmJkOTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDRlODMxZDRlZjE3NGU1NjhlYmNmNDEwY2FhOTAxODUgPSAkKCc8ZGl2IGlkPSJodG1sXzQ0ZTgzMWQ0ZWYxNzRlNTY4ZWJjZjQxMGNhYTkwMTg1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZU1hbHZlcm4gQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NDlmMTgwYmYzYTU0Y2M4YTAyOTY2MTg3MGRmYmQ5MS5zZXRDb250ZW50KGh0bWxfNDRlODMxZDRlZjE3NGU1NjhlYmNmNDEwY2FhOTAxODUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjBmYjQ2OGU4NjYwNDY3ODhhMTI2MDgyYzQyNjZiZjQuYmluZFBvcHVwKHBvcHVwXzg0OWYxODBiZjNhNTRjYzhhMDI5NjYxODcwZGZiZDkxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I5Mjg2NWU5ZTI1OTQzZWY4NDA4YTkwYjE4MjE5YzQ5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg0NTM1MSwtNzkuMTYwNDk3MDk5OTk5OTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTE2YmM0ZjVlM2Y4NGM0MDkwZDEyNmMxZTk2MTUxOGIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTY4YjFlNzcyODJkNDM1Zjg0ODFiNzU2ZDQ3ODFjOGMgPSAkKCc8ZGl2IGlkPSJodG1sX2E2OGIxZTc3MjgyZDQzNWY4NDgxYjc1NmQ0NzgxYzhjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdobGFuZCBDcmVla1JvdWdlIEhpbGxQb3J0IFVuaW9uIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTE2YmM0ZjVlM2Y4NGM0MDkwZDEyNmMxZTk2MTUxOGIuc2V0Q29udGVudChodG1sX2E2OGIxZTc3MjgyZDQzNWY4NDgxYjc1NmQ0NzgxYzhjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2I5Mjg2NWU5ZTI1OTQzZWY4NDA4YTkwYjE4MjE5YzQ5LmJpbmRQb3B1cChwb3B1cF85MTZiYzRmNWUzZjg0YzQwOTBkMTI2YzFlOTYxNTE4Yik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xYzFhYzNiNzkyMmQ0ZjU1YmQyZGI0NWJlOWIyMTBhMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MzU3MjYsLTc5LjE4ODcxMTVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTk1MzUzZTFiODExNGIzMGJiOTA5NTZkNWEzZDQzODEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYzk5ZjU0ZWU4NjY3NDczNTlhNmI2MWZkZmZmODYyZTggPSAkKCc8ZGl2IGlkPSJodG1sX2M5OWY1NGVlODY2NzQ3MzU5YTZiNjFmZGZmZjg2MmU4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HdWlsZHdvb2RNb3JuaW5nc2lkZVdlc3QgSGlsbCBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U5NTM1M2UxYjgxMTRiMzBiYjkwOTU2ZDVhM2Q0MzgxLnNldENvbnRlbnQoaHRtbF9jOTlmNTRlZTg2Njc0NzM1OWE2YjYxZmRmZmY4NjJlOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8xYzFhYzNiNzkyMmQ0ZjU1YmQyZGI0NWJlOWIyMTBhMS5iaW5kUG9wdXAocG9wdXBfZTk1MzUzZTFiODExNGIzMGJiOTA5NTZkNWEzZDQzODEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDYyODg1NDNkYTc2NDY3M2FjNDRhOGU4ZWYxYjIxZjUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzA5OTIxLC03OS4yMTY5MTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmYwMDAwIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xOTdkMTIwNGE1N2Y0NjhhOGZiZDFkOTRiZTJiYzBiMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iMDY2ZGZjODY1OGQ0NGVhYTQ4YWI2N2EyZGE1ODcxMSA9ICQoJzxkaXYgaWQ9Imh0bWxfYjA2NmRmYzg2NThkNDRlYWE0OGFiNjdhMmRhNTg3MTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldvYnVybiBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzE5N2QxMjA0YTU3ZjQ2OGE4ZmJkMWQ5NGJlMmJjMGIyLnNldENvbnRlbnQoaHRtbF9iMDY2ZGZjODY1OGQ0NGVhYTQ4YWI2N2EyZGE1ODcxMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kNjI4ODU0M2RhNzY0NjczYWM0NGE4ZThlZjFiMjFmNS5iaW5kUG9wdXAocG9wdXBfMTk3ZDEyMDRhNTdmNDY4YThmYmQxZDk0YmUyYmMwYjIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNzkwNzcxMDM5MmM1NDRkZGE3MWRkOWY5ZmI4YzhkOTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzMxMzYsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzExNjE4ZTJkNzM5MTQ3Mjk5NDVlN2RhODU0MmU2YjFhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2FhZjg5MDMxZmY0NjRlMGViZWFkNjNiMThlYWQwZmRiID0gJCgnPGRpdiBpZD0iaHRtbF9hYWY4OTAzMWZmNDY0ZTBlYmVhZDYzYjE4ZWFkMGZkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VkYXJicmFlIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTE2MThlMmQ3MzkxNDcyOTk0NWU3ZGE4NTQyZTZiMWEuc2V0Q29udGVudChodG1sX2FhZjg5MDMxZmY0NjRlMGViZWFkNjNiMThlYWQwZmRiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzc5MDc3MTAzOTJjNTQ0ZGRhNzFkZDlmOWZiOGM4ZDk3LmJpbmRQb3B1cChwb3B1cF8xMTYxOGUyZDczOTE0NzI5OTQ1ZTdkYTg1NDJlNmIxYSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84OTcxNDU2M2Y0YTQ0ODgxOTc3NGIyNjQ2ZmRkNDllNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NDczNDIsLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRhMmUzZTgxMTg3MTQyYjU5Mzc3ZDcxMTkzMTAxMDNiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ1YjI1M2ZmZjk2YTQ5MzE4Y2I4NWY5NmUyODc3NmFmID0gJCgnPGRpdiBpZD0iaHRtbF80NWIyNTNmZmY5NmE0OTMxOGNiODVmOTZlMjg3NzZhZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U2NhcmJvcm91Z2ggVmlsbGFnZSBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRhMmUzZTgxMTg3MTQyYjU5Mzc3ZDcxMTkzMTAxMDNiLnNldENvbnRlbnQoaHRtbF80NWIyNTNmZmY5NmE0OTMxOGNiODVmOTZlMjg3NzZhZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84OTcxNDU2M2Y0YTQ0ODgxOTc3NGIyNjQ2ZmRkNDllNC5iaW5kUG9wdXAocG9wdXBfNGEyZTNlODExODcxNDJiNTkzNzdkNzExOTMxMDEwM2IpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTYwNmViN2MzYmJiNGJhZGJmYTNhYTY2NGNjODEzOGEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODBmZmI0IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwZmZiNCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81NTVlNGE3NDA0MGY0YzcwODE4NTFmMTAwYTg5YWNlNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hZDNlOGNiYWYyMzE0YzYyOWZjNjZhOGQ4MDI0NmQwYyA9ICQoJzxkaXYgaWQ9Imh0bWxfYWQzZThjYmFmMjMxNGM2MjlmYzY2YThkODAyNDZkMGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgQmlyY2htb3VudCBQYXJrSW9udmlld0tlbm5lZHkgUGFyayBDbHVzdGVyIDI8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU1NWU0YTc0MDQwZjRjNzA4MTg1MWYxMDBhODlhY2U0LnNldENvbnRlbnQoaHRtbF9hZDNlOGNiYWYyMzE0YzYyOWZjNjZhOGQ4MDI0NmQwYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81NjA2ZWI3YzNiYmI0YmFkYmZhM2FhNjY0Y2M4MTM4YS5iaW5kUG9wdXAocG9wdXBfNTU1ZTRhNzQwNDBmNGM3MDgxODUxZjEwMGE4OWFjZTQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2YyNDkwZThkMGYyNDRmZDg4NzNlNWJlNWU0OWMyNjQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTExMTE3MDAwMDAwMDQsLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjNkOWU0ZTdkMDFhNDgxN2I0ODE5YWE5ZjZjZWQ0ZDIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTgyNDY4OTk3MTc5NDFlMDk5NmExZjYyOWM0ZDlkOWMgPSAkKCc8ZGl2IGlkPSJodG1sXzE4MjQ2ODk5NzE3OTQxZTA5OTZhMWY2MjljNGQ5ZDljIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGFpcmxlYUdvbGRlbiBNaWxlT2FrcmlkZ2UgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yM2Q5ZTRlN2QwMWE0ODE3YjQ4MTlhYTlmNmNlZDRkMi5zZXRDb250ZW50KGh0bWxfMTgyNDY4OTk3MTc5NDFlMDk5NmExZjYyOWM0ZDlkOWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfY2YyNDkwZThkMGYyNDRmZDg4NzNlNWJlNWU0OWMyNjQuYmluZFBvcHVwKHBvcHVwXzIzZDllNGU3ZDAxYTQ4MTdiNDgxOWFhOWY2Y2VkNGQyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBkZDQzZjc3ZTU1MTQzYTk5ZjI0MjkwMDRmZTI4OTdlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE2MzE2LC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmYwMDAwIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iMTMxZjQ0ODI3YzU0ZDNkOTU0NmE4YzBiZGJkODRiNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83YzExN2ZiN2U1NGY0YjQxOGIwOWRkMjNhNzlkNGZhMyA9ICQoJzxkaXYgaWQ9Imh0bWxfN2MxMTdmYjdlNTRmNGI0MThiMDlkZDIzYTc5ZDRmYTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsaWZmY3Jlc3RDbGlmZnNpZGVTY2FyYm9yb3VnaCBWaWxsYWdlIFdlc3QgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iMTMxZjQ0ODI3YzU0ZDNkOTU0NmE4YzBiZGJkODRiNy5zZXRDb250ZW50KGh0bWxfN2MxMTdmYjdlNTRmNGI0MThiMDlkZDIzYTc5ZDRmYTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMGRkNDNmNzdlNTUxNDNhOTlmMjQyOTAwNGZlMjg5N2UuYmluZFBvcHVwKHBvcHVwX2IxMzFmNDQ4MjdjNTRkM2Q5NTQ2YThjMGJkYmQ4NGI3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZhNGJmMDNhMTFjNTQ2YTA4ZjY0ZDFjNDQ0OTlmNWQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkyNjU3MDAwMDAwMDA0LC03OS4yNjQ4NDgxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E0YWQxZTZlOTdjZDQ2N2ZiODQyYjQ4OWFkZjMwZjE5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMzNGI0NDRhOWNkYjRjMWFhZGQ5N2JlN2QxZTMwNzVkID0gJCgnPGRpdiBpZD0iaHRtbF8zMzRiNDQ0YTljZGI0YzFhYWRkOTdiZTdkMWUzMDc1ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmlyY2ggQ2xpZmZDbGlmZnNpZGUgV2VzdCBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E0YWQxZTZlOTdjZDQ2N2ZiODQyYjQ4OWFkZjMwZjE5LnNldENvbnRlbnQoaHRtbF8zMzRiNDQ0YTljZGI0YzFhYWRkOTdiZTdkMWUzMDc1ZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9mYTRiZjAzYTExYzU0NmEwOGY2NGQxYzQ0NDk5ZjVkNS5iaW5kUG9wdXAocG9wdXBfYTRhZDFlNmU5N2NkNDY3ZmI4NDJiNDg5YWRmMzBmMTkpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTNiYTRlZTgwN2Q5NDAwZWI3ODYxMGJhOTU2ZTM4ZTIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTc0MDk2LC03OS4yNzMzMDQwMDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODAwMGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iYTBjZGUyMjYyYmU0YzI5YWZjMzhiNjc0YWFkNjY3MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80YmJjNzYwMWVhZmM0YzhjODE0ODliMzY0OGFjMmMwOSA9ICQoJzxkaXYgaWQ9Imh0bWxfNGJiYzc2MDFlYWZjNGM4YzgxNDg5YjM2NDhhYzJjMDkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrU2NhcmJvcm91Z2ggVG93biBDZW50cmVXZXhmb3JkIEhlaWdodHMgQ2x1c3RlciAxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iYTBjZGUyMjYyYmU0YzI5YWZjMzhiNjc0YWFkNjY3MC5zZXRDb250ZW50KGh0bWxfNGJiYzc2MDFlYWZjNGM4YzgxNDg5YjM2NDhhYzJjMDkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfOTNiYTRlZTgwN2Q5NDAwZWI3ODYxMGJhOTU2ZTM4ZTIuYmluZFBvcHVwKHBvcHVwX2JhMGNkZTIyNjJiZTRjMjlhZmMzOGI2NzRhYWQ2NjcwKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RmMGJiZjBiNzgyZDQ4M2VhOTY2OGExODVjNjQ4NmNjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzUwMDcxNTAwMDAwMDA0LC03OS4yOTU4NDkxXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I2MWNkNzIyZDhlZTQxNTBhYWY5NDkyODhhZjg4M2M0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZjMTU5Yzc0YmYzZjQ1ODhhY2Q0ZDcxZGEwM2FkMmQ2ID0gJCgnPGRpdiBpZD0iaHRtbF9mYzE1OWM3NGJmM2Y0NTg4YWNkNGQ3MWRhMDNhZDJkNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TWFyeXZhbGVXZXhmb3JkIENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjYxY2Q3MjJkOGVlNDE1MGFhZjk0OTI4OGFmODgzYzQuc2V0Q29udGVudChodG1sX2ZjMTU5Yzc0YmYzZjQ1ODhhY2Q0ZDcxZGEwM2FkMmQ2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2RmMGJiZjBiNzgyZDQ4M2VhOTY2OGExODVjNjQ4NmNjLmJpbmRQb3B1cChwb3B1cF9iNjFjZDcyMmQ4ZWU0MTUwYWFmOTQ5Mjg4YWY4ODNjNCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xYzJkOWVkN2Q1NjI0OTk5OTQ2YTAzYzY2ZjA2ZmQyOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5NDIwMDMsLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiNmZjAwMDAiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2NhYTBiZDAxNDNjYzRkZmU5ODU3ZTc4M2Y1MzZmZjBkKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdlNzk5MDgwY2IyMDRmY2I5NGI2NGYzMGVlMzYyN2VmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2UzMmVmMjAwODk1NjRlZTI5MzJhNjM1OTBkNWFjMGQ1ID0gJCgnPGRpdiBpZD0iaHRtbF9lMzJlZjIwMDg5NTY0ZWUyOTMyYTYzNTkwZDVhYzBkNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QWdpbmNvdXJ0IENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2U3OTkwODBjYjIwNGZjYjk0YjY0ZjMwZWUzNjI3ZWYuc2V0Q29udGVudChodG1sX2UzMmVmMjAwODk1NjRlZTI5MzJhNjM1OTBkNWFjMGQ1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzFjMmQ5ZWQ3ZDU2MjQ5OTk5NDZhMDNjNjZmMDZmZDI5LmJpbmRQb3B1cChwb3B1cF83ZTc5OTA4MGNiMjA0ZmNiOTRiNjRmMzBlZTM2MjdlZik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iZTc0MTIxYWRjNGQ0ZjU1OTUwZDlmOTg0N2U0MTRkNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MTYzNzUsLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGJhMDhmZGUzZDZhNDBjNzlhMWM4NTBjNGQ2MTNiNGQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGRkNjg2MDU3ZjQxNDgwNDg0NTBlZjNjNmRlZjBkMTUgPSAkKCc8ZGl2IGlkPSJodG1sXzRkZDY4NjA1N2Y0MTQ4MDQ4NDUwZWYzYzZkZWYwZDE1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DbGFya3MgQ29ybmVyc1N1bGxpdmFuVGFtIE8mIzM5O1NoYW50ZXIgQ2x1c3RlciAwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84YmEwOGZkZTNkNmE0MGM3OWExYzg1MGM0ZDYxM2I0ZC5zZXRDb250ZW50KGh0bWxfNGRkNjg2MDU3ZjQxNDgwNDg0NTBlZjNjNmRlZjBkMTUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYmU3NDEyMWFkYzRkNGY1NTk1MGQ5Zjk4NDdlNDE0ZDcuYmluZFBvcHVwKHBvcHVwXzhiYTA4ZmRlM2Q2YTQwYzc5YTFjODUwYzRkNjEzYjRkKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I4M2M4Yzg0OWYxYjQ4YWRiMmU3YjIyZmQzZTliMDNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODE1MjUyMiwtNzkuMjg0NTc3Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjZmYwMDAwIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9jYWEwYmQwMTQzY2M0ZGZlOTg1N2U3ODNmNTM2ZmYwZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85ODJhNGMxN2M1OGY0YmNiOTk3NDY2ZjcxNjk0ODZjZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zMmU4OTUwMjI4OTQ0ZjQxOTE2MWVkMjFhZjkxY2RkOCA9ICQoJzxkaXYgaWQ9Imh0bWxfMzJlODk1MDIyODk0NGY0MTkxNjFlZDIxYWY5MWNkZDgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFnaW5jb3VydCBOb3J0aEwmIzM5O0Ftb3JlYXV4IEVhc3RNaWxsaWtlblN0ZWVsZXMgRWFzdCBDbHVzdGVyIDA8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk4MmE0YzE3YzU4ZjRiY2I5OTc0NjZmNzE2OTQ4NmNkLnNldENvbnRlbnQoaHRtbF8zMmU4OTUwMjI4OTQ0ZjQxOTE2MWVkMjFhZjkxY2RkOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iODNjOGM4NDlmMWI0OGFkYjJlN2IyMmZkM2U5YjAzZS5iaW5kUG9wdXAocG9wdXBfOTgyYTRjMTdjNThmNGJjYjk5NzQ2NmY3MTY5NDg2Y2QpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMGVhYjdlYWVjYWE0NDk4ZDhkMzFkOThmZjY2MDUzNjIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTk1MjUyMDAwMDAwMDUsLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2FhMGJkMDE0M2NjNGRmZTk4NTdlNzgzZjUzNmZmMGQpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2VhMDVhZjJmN2M2NDFmOGI0YmQ5OTE3ZTk1MjUxNGUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2FkNjQ5MTYwMGFiNDZlMWFhNmYzMDI3ZGQ3ZWNhMTkgPSAkKCc8ZGl2IGlkPSJodG1sX2NhZDY0OTE2MDBhYjQ2ZTFhYTZmMzAyN2RkN2VjYTE5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MJiMzOTtBbW9yZWF1eCBXZXN0U3RlZWxlcyBXZXN0IENsdXN0ZXIgMDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfM2VhMDVhZjJmN2M2NDFmOGI0YmQ5OTE3ZTk1MjUxNGUuc2V0Q29udGVudChodG1sX2NhZDY0OTE2MDBhYjQ2ZTFhYTZmMzAyN2RkN2VjYTE5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzBlYWI3ZWFlY2FhNDQ5OGQ4ZDMxZDk4ZmY2NjA1MzYyLmJpbmRQb3B1cChwb3B1cF8zZWEwNWFmMmY3YzY0MWY4YjRiZDk5MTdlOTUyNTE0ZSk7CgogICAgICAgICAgICAKICAgICAgICAKPC9zY3JpcHQ+\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7fd988332358>"
]
},
"execution_count": 48,
"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",
"markers_colors = []\n",
"for lat, lon, poi, cluster in zip(Scarborough_merged['Latitude'], Scarborough_merged['Longitude'], Scarborough_merged['Neighborhood'], Scarborough_merged['Cluster Labels']):\n",
" label = folium.Popup(str(poi) + ' Cluster ' + str(cluster), 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",
" \n",
"map_clusters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### verify the cluster1"
]
},
{
"cell_type": "code",
"execution_count": 49,
"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>Borough</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Labels</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Scarborough</td>\n",
" <td>43.806686</td>\n",
" <td>-79.194353</td>\n",
" <td>0</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Print Shop</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Scarborough</td>\n",
" <td>43.784535</td>\n",
" <td>-79.160497</td>\n",
" <td>0</td>\n",
" <td>Bar</td>\n",
" <td>Moving Target</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Scarborough</td>\n",
" <td>43.763573</td>\n",
" <td>-79.188711</td>\n",
" <td>0</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Mexican Restaurant</td>\n",
" <td>Spa</td>\n",
" <td>Medical Center</td>\n",
" <td>Electronics Store</td>\n",
" <td>Pizza Place</td>\n",
" <td>Rental Car Location</td>\n",
" <td>Department Store</td>\n",
" <td>College Stadium</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Scarborough</td>\n",
" <td>43.770992</td>\n",
" <td>-79.216917</td>\n",
" <td>0</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Korean Restaurant</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Scarborough</td>\n",
" <td>43.773136</td>\n",
" <td>-79.239476</td>\n",
" <td>0</td>\n",
" <td>Caribbean Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Bank</td>\n",
" <td>Hakka Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Athletics &amp; Sports</td>\n",
" <td>Auto Garage</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Scarborough</td>\n",
" <td>43.744734</td>\n",
" <td>-79.239476</td>\n",
" <td>0</td>\n",
" <td>Grocery Store</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Playground</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Scarborough</td>\n",
" <td>43.711112</td>\n",
" <td>-79.284577</td>\n",
" <td>0</td>\n",
" <td>Bakery</td>\n",
" <td>Bus Line</td>\n",
" <td>Intersection</td>\n",
" <td>Soccer Field</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Bus Station</td>\n",
" <td>Metro Station</td>\n",
" <td>Coffee Shop</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Scarborough</td>\n",
" <td>43.716316</td>\n",
" <td>-79.239476</td>\n",
" <td>0</td>\n",
" <td>American Restaurant</td>\n",
" <td>Motel</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>Scarborough</td>\n",
" <td>43.692657</td>\n",
" <td>-79.264848</td>\n",
" <td>0</td>\n",
" <td>General Entertainment</td>\n",
" <td>Skating Rink</td>\n",
" <td>Café</td>\n",
" <td>College Stadium</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Grocery Store</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Scarborough</td>\n",
" <td>43.750072</td>\n",
" <td>-79.295849</td>\n",
" <td>0</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Auto Garage</td>\n",
" <td>Shopping Mall</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Electronics Store</td>\n",
" <td>College Stadium</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Department Store</td>\n",
" <td>Discount Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Scarborough</td>\n",
" <td>43.794200</td>\n",
" <td>-79.262029</td>\n",
" <td>0</td>\n",
" <td>Clothing Store</td>\n",
" <td>Lounge</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>Scarborough</td>\n",
" <td>43.781638</td>\n",
" <td>-79.304302</td>\n",
" <td>0</td>\n",
" <td>Pizza Place</td>\n",
" <td>Noodle House</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Shopping Mall</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Clothing Store</td>\n",
" <td>Coffee Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Scarborough</td>\n",
" <td>43.815252</td>\n",
" <td>-79.284577</td>\n",
" <td>0</td>\n",
" <td>Park</td>\n",
" <td>Playground</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>General Entertainment</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Fried Chicken Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Electronics Store</td>\n",
" <td>Discount Store</td>\n",
" <td>Department Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Scarborough</td>\n",
" <td>43.799525</td>\n",
" <td>-79.318389</td>\n",
" <td>0</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Fast Food Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Grocery Store</td>\n",
" <td>Pharmacy</td>\n",
" <td>Pizza Place</td>\n",
" <td>Camera Store</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Borough Latitude Longitude Cluster Labels \\\n",
"0 Scarborough 43.806686 -79.194353 0 \n",
"1 Scarborough 43.784535 -79.160497 0 \n",
"2 Scarborough 43.763573 -79.188711 0 \n",
"3 Scarborough 43.770992 -79.216917 0 \n",
"4 Scarborough 43.773136 -79.239476 0 \n",
"5 Scarborough 43.744734 -79.239476 0 \n",
"7 Scarborough 43.711112 -79.284577 0 \n",
"8 Scarborough 43.716316 -79.239476 0 \n",
"9 Scarborough 43.692657 -79.264848 0 \n",
"11 Scarborough 43.750072 -79.295849 0 \n",
"12 Scarborough 43.794200 -79.262029 0 \n",
"13 Scarborough 43.781638 -79.304302 0 \n",
"14 Scarborough 43.815252 -79.284577 0 \n",
"15 Scarborough 43.799525 -79.318389 0 \n",
"\n",
" 1st Most Common Venue 2nd Most Common Venue 3rd Most Common Venue \\\n",
"0 Fast Food Restaurant Print Shop Vietnamese Restaurant \n",
"1 Bar Moving Target Vietnamese Restaurant \n",
"2 Breakfast Spot Mexican Restaurant Spa \n",
"3 Coffee Shop Korean Restaurant Indian Restaurant \n",
"4 Caribbean Restaurant Bakery Fried Chicken Joint \n",
"5 Grocery Store Cosmetics Shop Playground \n",
"7 Bakery Bus Line Intersection \n",
"8 American Restaurant Motel Clothing Store \n",
"9 General Entertainment Skating Rink Café \n",
"11 Middle Eastern Restaurant Sandwich Place Auto Garage \n",
"12 Clothing Store Lounge Breakfast Spot \n",
"13 Pizza Place Noodle House Thai Restaurant \n",
"14 Park Playground Vietnamese Restaurant \n",
"15 Chinese Restaurant Coffee Shop Fast Food Restaurant \n",
"\n",
" 4th Most Common Venue 5th Most Common Venue 6th Most Common Venue \\\n",
"0 Chinese Restaurant Grocery Store General Entertainment \n",
"1 Clothing Store Grocery Store General Entertainment \n",
"2 Medical Center Electronics Store Pizza Place \n",
"3 Vietnamese Restaurant Clothing Store Grocery Store \n",
"4 Bank Hakka Restaurant Thai Restaurant \n",
"5 Vietnamese Restaurant Chinese Restaurant General Entertainment \n",
"7 Soccer Field Fast Food Restaurant Bus Station \n",
"8 Grocery Store General Entertainment Furniture / Home Store \n",
"9 College Stadium Vietnamese Restaurant Clothing Store \n",
"11 Shopping Mall Breakfast Spot Electronics Store \n",
"12 Sandwich Place Chinese Restaurant Vietnamese Restaurant \n",
"13 Fried Chicken Joint Italian Restaurant Fast Food Restaurant \n",
"14 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"15 Sandwich Place Grocery Store Pharmacy \n",
"\n",
" 7th Most Common Venue 8th Most Common Venue 9th Most Common Venue \\\n",
"0 Furniture / Home Store Fried Chicken Joint Electronics Store \n",
"1 Furniture / Home Store Fried Chicken Joint Fast Food Restaurant \n",
"2 Rental Car Location Department Store College Stadium \n",
"3 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"4 Athletics & Sports Auto Garage Grocery Store \n",
"5 Furniture / Home Store Fried Chicken Joint Fast Food Restaurant \n",
"7 Metro Station Coffee Shop General Entertainment \n",
"8 Fried Chicken Joint Fast Food Restaurant Electronics Store \n",
"9 Grocery Store Furniture / Home Store Fried Chicken Joint \n",
"11 College Stadium Cosmetics Shop Department Store \n",
"12 General Entertainment Furniture / Home Store Fried Chicken Joint \n",
"13 Shopping Mall Chinese Restaurant Clothing Store \n",
"14 Fast Food Restaurant Electronics Store Discount Store \n",
"15 Pizza Place Camera Store Breakfast Spot \n",
"\n",
" 10th Most Common Venue \n",
"0 Discount Store \n",
"1 Electronics Store \n",
"2 Cosmetics Shop \n",
"3 Fast Food Restaurant \n",
"4 General Entertainment \n",
"5 Electronics Store \n",
"7 Furniture / Home Store \n",
"8 Discount Store \n",
"9 Fast Food Restaurant \n",
"11 Discount Store \n",
"12 Fast Food Restaurant \n",
"13 Coffee Shop \n",
"14 Department Store \n",
"15 Japanese Restaurant "
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_merged.loc[Scarborough_merged['Cluster Labels'] == 0, Scarborough_merged.columns[[1] + list(range(3, Scarborough_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Verify the cluster2"
]
},
{
"cell_type": "code",
"execution_count": 50,
"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>Borough</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Labels</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>Scarborough</td>\n",
" <td>43.75741</td>\n",
" <td>-79.273304</td>\n",
" <td>1</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Brewery</td>\n",
" <td>Furniture / Home Store</td>\n",
" <td>Latin American Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Pet Store</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Thrift / Vintage Store</td>\n",
" <td>Bar</td>\n",
" <td>College Stadium</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Borough Latitude Longitude Cluster Labels 1st Most Common Venue \\\n",
"10 Scarborough 43.75741 -79.273304 1 Indian Restaurant \n",
"\n",
" 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
"10 Brewery Furniture / Home Store Latin American Restaurant \n",
"\n",
" 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
"10 Chinese Restaurant Pet Store Vietnamese Restaurant \n",
"\n",
" 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
"10 Thrift / Vintage Store Bar College Stadium "
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_merged.loc[Scarborough_merged['Cluster Labels'] == 1, Scarborough_merged.columns[[1] + list(range(3, Scarborough_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### verify the cluster3"
]
},
{
"cell_type": "code",
"execution_count": 51,
"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>Borough</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Labels</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Scarborough</td>\n",
" <td>43.727929</td>\n",
" <td>-79.262029</td>\n",
" <td>2</td>\n",
" <td>Discount Store</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Bus Station</td>\n",
" <td>Department Store</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Train Station</td>\n",
" <td>Bar</td>\n",
" <td>Cosmetics Shop</td>\n",
" <td>Hakka Restaurant</td>\n",
" <td>Grocery Store</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Borough Latitude Longitude Cluster Labels 1st Most Common Venue \\\n",
"6 Scarborough 43.727929 -79.262029 2 Discount Store \n",
"\n",
" 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
"6 Chinese Restaurant Bus Station Department Store \n",
"\n",
" 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
"6 Coffee Shop Train Station Bar \n",
"\n",
" 8th Most Common Venue 9th Most Common Venue 10th Most Common Venue \n",
"6 Cosmetics Shop Hakka Restaurant Grocery Store "
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Scarborough_merged.loc[Scarborough_merged['Cluster Labels'] == 2, Scarborough_merged.columns[[1] + list(range(3, Scarborough_merged.shape[1]))]]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment