cmc/data-science

Personal data science learning files.

clone: git clone https://gitbay.org/cmc/data-science.git

main: notebooks/Segmenting_and_Clustering_Neighbourhoods_in_Toronto.ipynb · raw

   1{
   2 "cells": [
   3  {
   4   "cell_type": "markdown",
   5   "metadata": {},
   6   "source": [
   7    "# Segmenting and Clustering Neighbourhoods in Toronto\n",
   8    "---\n",
   9    "# Part 1\n",
  10    "Import libraries"
  11   ]
  12  },
  13  {
  14   "cell_type": "code",
  15   "execution_count": 68,
  16   "metadata": {},
  17   "outputs": [],
  18   "source": [
  19    "import pandas as pd\n",
  20    "import numpy as np\n",
  21    "import requests"
  22   ]
  23  },
  24  {
  25   "cell_type": "markdown",
  26   "metadata": {},
  27   "source": [
  28    "Get the HTML page of Wikipedia and use read_html we convert the html data into list of Data frame objects.\n",
  29    "\n",
  30    "Remove cells which have neighbourhood as \"Not assigned.\""
  31   ]
  32  },
  33  {
  34   "cell_type": "code",
  35   "execution_count": 69,
  36   "metadata": {},
  37   "outputs": [
  38    {
  39     "data": {
  40      "text/html": [
  41       "<div>\n",
  42       "<style scoped>\n",
  43       "    .dataframe tbody tr th:only-of-type {\n",
  44       "        vertical-align: middle;\n",
  45       "    }\n",
  46       "\n",
  47       "    .dataframe tbody tr th {\n",
  48       "        vertical-align: top;\n",
  49       "    }\n",
  50       "\n",
  51       "    .dataframe thead th {\n",
  52       "        text-align: right;\n",
  53       "    }\n",
  54       "</style>\n",
  55       "<table border=\"1\" class=\"dataframe\">\n",
  56       "  <thead>\n",
  57       "    <tr style=\"text-align: right;\">\n",
  58       "      <th></th>\n",
  59       "      <th>Postal Code</th>\n",
  60       "      <th>Borough</th>\n",
  61       "      <th>Neighbourhood</th>\n",
  62       "    </tr>\n",
  63       "  </thead>\n",
  64       "  <tbody>\n",
  65       "    <tr>\n",
  66       "      <th>0</th>\n",
  67       "      <td>M3A</td>\n",
  68       "      <td>North York</td>\n",
  69       "      <td>Parkwoods</td>\n",
  70       "    </tr>\n",
  71       "    <tr>\n",
  72       "      <th>1</th>\n",
  73       "      <td>M4A</td>\n",
  74       "      <td>North York</td>\n",
  75       "      <td>Victoria Village</td>\n",
  76       "    </tr>\n",
  77       "    <tr>\n",
  78       "      <th>2</th>\n",
  79       "      <td>M5A</td>\n",
  80       "      <td>Downtown Toronto</td>\n",
  81       "      <td>Regent Park, Harbourfront</td>\n",
  82       "    </tr>\n",
  83       "    <tr>\n",
  84       "      <th>3</th>\n",
  85       "      <td>M6A</td>\n",
  86       "      <td>North York</td>\n",
  87       "      <td>Lawrence Manor, Lawrence Heights</td>\n",
  88       "    </tr>\n",
  89       "    <tr>\n",
  90       "      <th>4</th>\n",
  91       "      <td>M7A</td>\n",
  92       "      <td>Downtown Toronto</td>\n",
  93       "      <td>Queen's Park, Ontario Provincial Government</td>\n",
  94       "    </tr>\n",
  95       "  </tbody>\n",
  96       "</table>\n",
  97       "</div>"
  98      ],
  99      "text/plain": [
 100       "  Postal Code           Borough                                Neighbourhood\n",
 101       "0         M3A        North York                                    Parkwoods\n",
 102       "1         M4A        North York                             Victoria Village\n",
 103       "2         M5A  Downtown Toronto                    Regent Park, Harbourfront\n",
 104       "3         M6A        North York             Lawrence Manor, Lawrence Heights\n",
 105       "4         M7A  Downtown Toronto  Queen's Park, Ontario Provincial Government"
 106      ]
 107     },
 108     "execution_count": 69,
 109     "metadata": {},
 110     "output_type": "execute_result"
 111    }
 112   ],
 113   "source": [
 114    "wiki = 'https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M'\n",
 115    "wiki_page = requests.get(wiki)\n",
 116    "\n",
 117    "wiki_raw = pd.read_html(wiki_page.content, header = 0)[0]\n",
 118    "df = wiki_raw[wiki_raw.Neighbourhood != 'Not assigned']\n",
 119    "df.reset_index(inplace=True, drop=True)\n",
 120    "df.head()"
 121   ]
 122  },
 123  {
 124   "cell_type": "code",
 125   "execution_count": 70,
 126   "metadata": {},
 127   "outputs": [
 128    {
 129     "data": {
 130      "text/html": [
 131       "<div>\n",
 132       "<style scoped>\n",
 133       "    .dataframe tbody tr th:only-of-type {\n",
 134       "        vertical-align: middle;\n",
 135       "    }\n",
 136       "\n",
 137       "    .dataframe tbody tr th {\n",
 138       "        vertical-align: top;\n",
 139       "    }\n",
 140       "\n",
 141       "    .dataframe thead th {\n",
 142       "        text-align: right;\n",
 143       "    }\n",
 144       "</style>\n",
 145       "<table border=\"1\" class=\"dataframe\">\n",
 146       "  <thead>\n",
 147       "    <tr style=\"text-align: right;\">\n",
 148       "      <th></th>\n",
 149       "      <th>Borough</th>\n",
 150       "      <th>Neighbourhood</th>\n",
 151       "    </tr>\n",
 152       "    <tr>\n",
 153       "      <th>Postal Code</th>\n",
 154       "      <th></th>\n",
 155       "      <th></th>\n",
 156       "    </tr>\n",
 157       "  </thead>\n",
 158       "  <tbody>\n",
 159       "    <tr>\n",
 160       "      <th>M1B</th>\n",
 161       "      <td>Scarborough</td>\n",
 162       "      <td>Malvern, Rouge</td>\n",
 163       "    </tr>\n",
 164       "    <tr>\n",
 165       "      <th>M1C</th>\n",
 166       "      <td>Scarborough</td>\n",
 167       "      <td>Rouge Hill, Port Union, Highland Creek</td>\n",
 168       "    </tr>\n",
 169       "    <tr>\n",
 170       "      <th>M1E</th>\n",
 171       "      <td>Scarborough</td>\n",
 172       "      <td>Guildwood, Morningside, West Hill</td>\n",
 173       "    </tr>\n",
 174       "    <tr>\n",
 175       "      <th>M1G</th>\n",
 176       "      <td>Scarborough</td>\n",
 177       "      <td>Woburn</td>\n",
 178       "    </tr>\n",
 179       "    <tr>\n",
 180       "      <th>M1H</th>\n",
 181       "      <td>Scarborough</td>\n",
 182       "      <td>Cedarbrae</td>\n",
 183       "    </tr>\n",
 184       "    <tr>\n",
 185       "      <th>...</th>\n",
 186       "      <td>...</td>\n",
 187       "      <td>...</td>\n",
 188       "    </tr>\n",
 189       "    <tr>\n",
 190       "      <th>M9N</th>\n",
 191       "      <td>York</td>\n",
 192       "      <td>Weston</td>\n",
 193       "    </tr>\n",
 194       "    <tr>\n",
 195       "      <th>M9P</th>\n",
 196       "      <td>Etobicoke</td>\n",
 197       "      <td>Westmount</td>\n",
 198       "    </tr>\n",
 199       "    <tr>\n",
 200       "      <th>M9R</th>\n",
 201       "      <td>Etobicoke</td>\n",
 202       "      <td>Kingsview Village, St. Phillips, Martin Grove ...</td>\n",
 203       "    </tr>\n",
 204       "    <tr>\n",
 205       "      <th>M9V</th>\n",
 206       "      <td>Etobicoke</td>\n",
 207       "      <td>South Steeles, Silverstone, Humbergate, Jamest...</td>\n",
 208       "    </tr>\n",
 209       "    <tr>\n",
 210       "      <th>M9W</th>\n",
 211       "      <td>Etobicoke</td>\n",
 212       "      <td>Northwest, West Humber - Clairville</td>\n",
 213       "    </tr>\n",
 214       "  </tbody>\n",
 215       "</table>\n",
 216       "<p>103 rows × 2 columns</p>\n",
 217       "</div>"
 218      ],
 219      "text/plain": [
 220       "                 Borough                                      Neighbourhood\n",
 221       "Postal Code                                                                \n",
 222       "M1B          Scarborough                                     Malvern, Rouge\n",
 223       "M1C          Scarborough             Rouge Hill, Port Union, Highland Creek\n",
 224       "M1E          Scarborough                  Guildwood, Morningside, West Hill\n",
 225       "M1G          Scarborough                                             Woburn\n",
 226       "M1H          Scarborough                                          Cedarbrae\n",
 227       "...                  ...                                                ...\n",
 228       "M9N                 York                                             Weston\n",
 229       "M9P            Etobicoke                                          Westmount\n",
 230       "M9R            Etobicoke  Kingsview Village, St. Phillips, Martin Grove ...\n",
 231       "M9V            Etobicoke  South Steeles, Silverstone, Humbergate, Jamest...\n",
 232       "M9W            Etobicoke                Northwest, West Humber - Clairville\n",
 233       "\n",
 234       "[103 rows x 2 columns]"
 235      ]
 236     },
 237     "execution_count": 70,
 238     "metadata": {},
 239     "output_type": "execute_result"
 240    }
 241   ],
 242   "source": [
 243    "df.groupby(['Postal Code']).first()"
 244   ]
 245  },
 246  {
 247   "cell_type": "code",
 248   "execution_count": 71,
 249   "metadata": {},
 250   "outputs": [
 251    {
 252     "data": {
 253      "text/plain": [
 254       "103"
 255      ]
 256     },
 257     "execution_count": 71,
 258     "metadata": {},
 259     "output_type": "execute_result"
 260    }
 261   ],
 262   "source": [
 263    "len(df['Postal Code'].unique())"
 264   ]
 265  },
 266  {
 267   "cell_type": "code",
 268   "execution_count": 72,
 269   "metadata": {},
 270   "outputs": [
 271    {
 272     "data": {
 273      "text/html": [
 274       "<div>\n",
 275       "<style scoped>\n",
 276       "    .dataframe tbody tr th:only-of-type {\n",
 277       "        vertical-align: middle;\n",
 278       "    }\n",
 279       "\n",
 280       "    .dataframe tbody tr th {\n",
 281       "        vertical-align: top;\n",
 282       "    }\n",
 283       "\n",
 284       "    .dataframe thead th {\n",
 285       "        text-align: right;\n",
 286       "    }\n",
 287       "</style>\n",
 288       "<table border=\"1\" class=\"dataframe\">\n",
 289       "  <thead>\n",
 290       "    <tr style=\"text-align: right;\">\n",
 291       "      <th></th>\n",
 292       "      <th>Postal Code</th>\n",
 293       "      <th>Borough</th>\n",
 294       "      <th>Neighbourhood</th>\n",
 295       "    </tr>\n",
 296       "  </thead>\n",
 297       "  <tbody>\n",
 298       "  </tbody>\n",
 299       "</table>\n",
 300       "</div>"
 301      ],
 302      "text/plain": [
 303       "Empty DataFrame\n",
 304       "Columns: [Postal Code, Borough, Neighbourhood]\n",
 305       "Index: []"
 306      ]
 307     },
 308     "execution_count": 72,
 309     "metadata": {},
 310     "output_type": "execute_result"
 311    }
 312   ],
 313   "source": [
 314    "df[df['Borough'] == 'Not assigned']"
 315   ]
 316  },
 317  {
 318   "cell_type": "code",
 319   "execution_count": 73,
 320   "metadata": {},
 321   "outputs": [
 322    {
 323     "data": {
 324      "text/plain": [
 325       "(103, 3)"
 326      ]
 327     },
 328     "execution_count": 73,
 329     "metadata": {},
 330     "output_type": "execute_result"
 331    }
 332   ],
 333   "source": [
 334    "df.shape"
 335   ]
 336  },
 337  {
 338   "cell_type": "markdown",
 339   "metadata": {},
 340   "source": [
 341    "---\n",
 342    "# Part 2"
 343   ]
 344  },
 345  {
 346   "cell_type": "code",
 347   "execution_count": 74,
 348   "metadata": {},
 349   "outputs": [
 350    {
 351     "name": "stdout",
 352     "output_type": "stream",
 353     "text": [
 354      "Requirement already satisfied: geocoder in c:\\users\\my_user\\anaconda3\\lib\\site-packages (1.38.1)\n",
 355      "Requirement already satisfied: future in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.18.2)\n",
 356      "Requirement already satisfied: ratelim in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (0.1.6)\n",
 357      "Requirement already satisfied: requests in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (2.22.0)\n",
 358      "Requirement already satisfied: click in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (7.0)\n",
 359      "Requirement already satisfied: six in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from geocoder) (1.14.0)\n",
 360      "Requirement already satisfied: decorator in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from ratelim->geocoder) (4.4.1)\n",
 361      "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (1.25.8)\n",
 362      "Requirement already satisfied: idna<2.9,>=2.5 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2.8)\n",
 363      "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (2019.11.28)\n",
 364      "Requirement already satisfied: chardet<3.1.0,>=3.0.2 in c:\\users\\my_user\\anaconda3\\lib\\site-packages (from requests->geocoder) (3.0.4)\n",
 365      "Note: you may need to restart the kernel to use updated packages.\n"
 366     ]
 367    }
 368   ],
 369   "source": [
 370    "pip install geocoder"
 371   ]
 372  },
 373  {
 374   "cell_type": "code",
 375   "execution_count": 75,
 376   "metadata": {},
 377   "outputs": [],
 378   "source": [
 379    "import geocoder"
 380   ]
 381  },
 382  {
 383   "cell_type": "code",
 384   "execution_count": 76,
 385   "metadata": {},
 386   "outputs": [
 387    {
 388     "data": {
 389      "text/html": [
 390       "<div>\n",
 391       "<style scoped>\n",
 392       "    .dataframe tbody tr th:only-of-type {\n",
 393       "        vertical-align: middle;\n",
 394       "    }\n",
 395       "\n",
 396       "    .dataframe tbody tr th {\n",
 397       "        vertical-align: top;\n",
 398       "    }\n",
 399       "\n",
 400       "    .dataframe thead th {\n",
 401       "        text-align: right;\n",
 402       "    }\n",
 403       "</style>\n",
 404       "<table border=\"1\" class=\"dataframe\">\n",
 405       "  <thead>\n",
 406       "    <tr style=\"text-align: right;\">\n",
 407       "      <th></th>\n",
 408       "      <th>Postal Code</th>\n",
 409       "      <th>Latitude</th>\n",
 410       "      <th>Longitude</th>\n",
 411       "    </tr>\n",
 412       "  </thead>\n",
 413       "  <tbody>\n",
 414       "    <tr>\n",
 415       "      <th>0</th>\n",
 416       "      <td>M1B</td>\n",
 417       "      <td>43.806686</td>\n",
 418       "      <td>-79.194353</td>\n",
 419       "    </tr>\n",
 420       "    <tr>\n",
 421       "      <th>1</th>\n",
 422       "      <td>M1C</td>\n",
 423       "      <td>43.784535</td>\n",
 424       "      <td>-79.160497</td>\n",
 425       "    </tr>\n",
 426       "    <tr>\n",
 427       "      <th>2</th>\n",
 428       "      <td>M1E</td>\n",
 429       "      <td>43.763573</td>\n",
 430       "      <td>-79.188711</td>\n",
 431       "    </tr>\n",
 432       "    <tr>\n",
 433       "      <th>3</th>\n",
 434       "      <td>M1G</td>\n",
 435       "      <td>43.770992</td>\n",
 436       "      <td>-79.216917</td>\n",
 437       "    </tr>\n",
 438       "    <tr>\n",
 439       "      <th>4</th>\n",
 440       "      <td>M1H</td>\n",
 441       "      <td>43.773136</td>\n",
 442       "      <td>-79.239476</td>\n",
 443       "    </tr>\n",
 444       "  </tbody>\n",
 445       "</table>\n",
 446       "</div>"
 447      ],
 448      "text/plain": [
 449       "  Postal Code   Latitude  Longitude\n",
 450       "0         M1B  43.806686 -79.194353\n",
 451       "1         M1C  43.784535 -79.160497\n",
 452       "2         M1E  43.763573 -79.188711\n",
 453       "3         M1G  43.770992 -79.216917\n",
 454       "4         M1H  43.773136 -79.239476"
 455      ]
 456     },
 457     "execution_count": 76,
 458     "metadata": {},
 459     "output_type": "execute_result"
 460    }
 461   ],
 462   "source": [
 463    "url = 'http://cocl.us/Geospatial_data'\n",
 464    "df_geo = pd.read_csv(url)\n",
 465    "df_geo.head()"
 466   ]
 467  },
 468  {
 469   "cell_type": "code",
 470   "execution_count": 77,
 471   "metadata": {},
 472   "outputs": [
 473    {
 474     "data": {
 475      "text/plain": [
 476       "Postal Code     object\n",
 477       "Latitude       float64\n",
 478       "Longitude      float64\n",
 479       "dtype: object"
 480      ]
 481     },
 482     "execution_count": 77,
 483     "metadata": {},
 484     "output_type": "execute_result"
 485    }
 486   ],
 487   "source": [
 488    "df_geo.dtypes"
 489   ]
 490  },
 491  {
 492   "cell_type": "code",
 493   "execution_count": 78,
 494   "metadata": {},
 495   "outputs": [
 496    {
 497     "data": {
 498      "text/plain": [
 499       "Postal Code      object\n",
 500       "Borough          object\n",
 501       "Neighbourhood    object\n",
 502       "dtype: object"
 503      ]
 504     },
 505     "execution_count": 78,
 506     "metadata": {},
 507     "output_type": "execute_result"
 508    }
 509   ],
 510   "source": [
 511    "df.dtypes"
 512   ]
 513  },
 514  {
 515   "cell_type": "code",
 516   "execution_count": 79,
 517   "metadata": {},
 518   "outputs": [
 519    {
 520     "data": {
 521      "text/plain": [
 522       "(103, 3)"
 523      ]
 524     },
 525     "execution_count": 79,
 526     "metadata": {},
 527     "output_type": "execute_result"
 528    }
 529   ],
 530   "source": [
 531    "df.shape"
 532   ]
 533  },
 534  {
 535   "cell_type": "code",
 536   "execution_count": 80,
 537   "metadata": {},
 538   "outputs": [
 539    {
 540     "data": {
 541      "text/plain": [
 542       "(103, 3)"
 543      ]
 544     },
 545     "execution_count": 80,
 546     "metadata": {},
 547     "output_type": "execute_result"
 548    }
 549   ],
 550   "source": [
 551    "df_geo.shape"
 552   ]
 553  },
 554  {
 555   "cell_type": "code",
 556   "execution_count": 81,
 557   "metadata": {},
 558   "outputs": [
 559    {
 560     "data": {
 561      "text/html": [
 562       "<div>\n",
 563       "<style scoped>\n",
 564       "    .dataframe tbody tr th:only-of-type {\n",
 565       "        vertical-align: middle;\n",
 566       "    }\n",
 567       "\n",
 568       "    .dataframe tbody tr th {\n",
 569       "        vertical-align: top;\n",
 570       "    }\n",
 571       "\n",
 572       "    .dataframe thead th {\n",
 573       "        text-align: right;\n",
 574       "    }\n",
 575       "</style>\n",
 576       "<table border=\"1\" class=\"dataframe\">\n",
 577       "  <thead>\n",
 578       "    <tr style=\"text-align: right;\">\n",
 579       "      <th></th>\n",
 580       "      <th>Postal Code</th>\n",
 581       "      <th>Borough</th>\n",
 582       "      <th>Neighbourhood</th>\n",
 583       "      <th>Latitude</th>\n",
 584       "      <th>Longitude</th>\n",
 585       "    </tr>\n",
 586       "  </thead>\n",
 587       "  <tbody>\n",
 588       "    <tr>\n",
 589       "      <th>0</th>\n",
 590       "      <td>M3A</td>\n",
 591       "      <td>North York</td>\n",
 592       "      <td>Parkwoods</td>\n",
 593       "      <td>43.753259</td>\n",
 594       "      <td>-79.329656</td>\n",
 595       "    </tr>\n",
 596       "    <tr>\n",
 597       "      <th>1</th>\n",
 598       "      <td>M4A</td>\n",
 599       "      <td>North York</td>\n",
 600       "      <td>Victoria Village</td>\n",
 601       "      <td>43.725882</td>\n",
 602       "      <td>-79.315572</td>\n",
 603       "    </tr>\n",
 604       "    <tr>\n",
 605       "      <th>2</th>\n",
 606       "      <td>M5A</td>\n",
 607       "      <td>Downtown Toronto</td>\n",
 608       "      <td>Regent Park, Harbourfront</td>\n",
 609       "      <td>43.654260</td>\n",
 610       "      <td>-79.360636</td>\n",
 611       "    </tr>\n",
 612       "    <tr>\n",
 613       "      <th>3</th>\n",
 614       "      <td>M6A</td>\n",
 615       "      <td>North York</td>\n",
 616       "      <td>Lawrence Manor, Lawrence Heights</td>\n",
 617       "      <td>43.718518</td>\n",
 618       "      <td>-79.464763</td>\n",
 619       "    </tr>\n",
 620       "    <tr>\n",
 621       "      <th>4</th>\n",
 622       "      <td>M7A</td>\n",
 623       "      <td>Downtown Toronto</td>\n",
 624       "      <td>Queen's Park, Ontario Provincial Government</td>\n",
 625       "      <td>43.662301</td>\n",
 626       "      <td>-79.389494</td>\n",
 627       "    </tr>\n",
 628       "    <tr>\n",
 629       "      <th>5</th>\n",
 630       "      <td>M9A</td>\n",
 631       "      <td>Etobicoke</td>\n",
 632       "      <td>Islington Avenue, Humber Valley Village</td>\n",
 633       "      <td>43.667856</td>\n",
 634       "      <td>-79.532242</td>\n",
 635       "    </tr>\n",
 636       "    <tr>\n",
 637       "      <th>6</th>\n",
 638       "      <td>M1B</td>\n",
 639       "      <td>Scarborough</td>\n",
 640       "      <td>Malvern, Rouge</td>\n",
 641       "      <td>43.806686</td>\n",
 642       "      <td>-79.194353</td>\n",
 643       "    </tr>\n",
 644       "    <tr>\n",
 645       "      <th>7</th>\n",
 646       "      <td>M3B</td>\n",
 647       "      <td>North York</td>\n",
 648       "      <td>Don Mills</td>\n",
 649       "      <td>43.745906</td>\n",
 650       "      <td>-79.352188</td>\n",
 651       "    </tr>\n",
 652       "    <tr>\n",
 653       "      <th>8</th>\n",
 654       "      <td>M4B</td>\n",
 655       "      <td>East York</td>\n",
 656       "      <td>Parkview Hill, Woodbine Gardens</td>\n",
 657       "      <td>43.706397</td>\n",
 658       "      <td>-79.309937</td>\n",
 659       "    </tr>\n",
 660       "    <tr>\n",
 661       "      <th>9</th>\n",
 662       "      <td>M5B</td>\n",
 663       "      <td>Downtown Toronto</td>\n",
 664       "      <td>Garden District, Ryerson</td>\n",
 665       "      <td>43.657162</td>\n",
 666       "      <td>-79.378937</td>\n",
 667       "    </tr>\n",
 668       "    <tr>\n",
 669       "      <th>10</th>\n",
 670       "      <td>M6B</td>\n",
 671       "      <td>North York</td>\n",
 672       "      <td>Glencairn</td>\n",
 673       "      <td>43.709577</td>\n",
 674       "      <td>-79.445073</td>\n",
 675       "    </tr>\n",
 676       "    <tr>\n",
 677       "      <th>11</th>\n",
 678       "      <td>M9B</td>\n",
 679       "      <td>Etobicoke</td>\n",
 680       "      <td>West Deane Park, Princess Gardens, Martin Grov...</td>\n",
 681       "      <td>43.650943</td>\n",
 682       "      <td>-79.554724</td>\n",
 683       "    </tr>\n",
 684       "  </tbody>\n",
 685       "</table>\n",
 686       "</div>"
 687      ],
 688      "text/plain": [
 689       "   Postal Code           Borough  \\\n",
 690       "0          M3A        North York   \n",
 691       "1          M4A        North York   \n",
 692       "2          M5A  Downtown Toronto   \n",
 693       "3          M6A        North York   \n",
 694       "4          M7A  Downtown Toronto   \n",
 695       "5          M9A         Etobicoke   \n",
 696       "6          M1B       Scarborough   \n",
 697       "7          M3B        North York   \n",
 698       "8          M4B         East York   \n",
 699       "9          M5B  Downtown Toronto   \n",
 700       "10         M6B        North York   \n",
 701       "11         M9B         Etobicoke   \n",
 702       "\n",
 703       "                                        Neighbourhood   Latitude  Longitude  \n",
 704       "0                                           Parkwoods  43.753259 -79.329656  \n",
 705       "1                                    Victoria Village  43.725882 -79.315572  \n",
 706       "2                           Regent Park, Harbourfront  43.654260 -79.360636  \n",
 707       "3                    Lawrence Manor, Lawrence Heights  43.718518 -79.464763  \n",
 708       "4         Queen's Park, Ontario Provincial Government  43.662301 -79.389494  \n",
 709       "5             Islington Avenue, Humber Valley Village  43.667856 -79.532242  \n",
 710       "6                                      Malvern, Rouge  43.806686 -79.194353  \n",
 711       "7                                           Don Mills  43.745906 -79.352188  \n",
 712       "8                     Parkview Hill, Woodbine Gardens  43.706397 -79.309937  \n",
 713       "9                            Garden District, Ryerson  43.657162 -79.378937  \n",
 714       "10                                          Glencairn  43.709577 -79.445073  \n",
 715       "11  West Deane Park, Princess Gardens, Martin Grov...  43.650943 -79.554724  "
 716      ]
 717     },
 718     "execution_count": 81,
 719     "metadata": {},
 720     "output_type": "execute_result"
 721    }
 722   ],
 723   "source": [
 724    "df = df.join(df_geo.set_index('Postal Code'), on='Postal Code')\n",
 725    "df.head(12)"
 726   ]
 727  },
 728  {
 729   "cell_type": "code",
 730   "execution_count": 82,
 731   "metadata": {},
 732   "outputs": [
 733    {
 734     "data": {
 735      "text/plain": [
 736       "(103, 5)"
 737      ]
 738     },
 739     "execution_count": 82,
 740     "metadata": {},
 741     "output_type": "execute_result"
 742    }
 743   ],
 744   "source": [
 745    "df.shape"
 746   ]
 747  },
 748  {
 749   "cell_type": "markdown",
 750   "metadata": {},
 751   "source": [
 752    "---\n",
 753    "# Part 3\n",
 754    "Using the foursquere API to segment and cluster the neighborhoods of Toronto"
 755   ]
 756  },
 757  {
 758   "cell_type": "code",
 759   "execution_count": 85,
 760   "metadata": {},
 761   "outputs": [
 762    {
 763     "name": "stdout",
 764     "output_type": "stream",
 765     "text": [
 766      "Collecting package metadata (current_repodata.json): ...working... done\n",
 767      "Solving environment: ...working... done\n",
 768      "\n",
 769      "# All requested packages already installed.\n",
 770      "\n",
 771      "Collecting geopy\n",
 772      "  Downloading geopy-2.0.0-py3-none-any.whl (111 kB)\n",
 773      "Collecting geographiclib<2,>=1.49\n",
 774      "  Downloading geographiclib-1.50-py3-none-any.whl (38 kB)\n",
 775      "Installing collected packages: geographiclib, geopy\n",
 776      "Successfully installed geographiclib-1.50 geopy-2.0.0\n",
 777      "The geograpical coordinate of Toronto are 43.6534817, -79.3839347.\n"
 778     ]
 779    }
 780   ],
 781   "source": [
 782    "!conda install -c conda-forge geocoder --yes\n",
 783    "import geocoder\n",
 784    "!pip install geopy\n",
 785    "from geopy.geocoders import Nominatim \n",
 786    "\n",
 787    "address = 'Toronto, Ontario'\n",
 788    "\n",
 789    "geolocator = Nominatim(user_agent=\"toronto_explorer\")\n",
 790    "location = geolocator.geocode(address)\n",
 791    "latitude = location.latitude\n",
 792    "longitude = location.longitude\n",
 793    "print('The geograpical coordinate of Toronto are {}, {}.'.format(latitude, longitude))"
 794   ]
 795  },
 796  {
 797   "cell_type": "markdown",
 798   "metadata": {},
 799   "source": [
 800    "Printing the map"
 801   ]
 802  },
 803  {
 804   "cell_type": "code",
 805   "execution_count": 89,
 806   "metadata": {},
 807   "outputs": [
 808    {
 809     "data": {
 810      "text/html": [
 811       "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgCiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgTF9OT19UT1VDSCA9IGZhbHNlOwogICAgICAgICAgICBMX0RJU0FCTEVfM0QgPSBmYWxzZTsKICAgICAgICA8L3NjcmlwdD4KICAgIAogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY29kZS5qcXVlcnkuY29tL2pxdWVyeS0xLjEyLjQubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5qcyI+PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMi4wL2Nzcy9ib290c3RyYXAubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLXRoZW1lLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9mb250LWF3ZXNvbWUvNC42LjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL0xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLzIuMC4yL2xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3Jhd2Nkbi5naXRoYWNrLmNvbS9weXRob24tdmlzdWFsaXphdGlvbi9mb2xpdW0vbWFzdGVyL2ZvbGl1bS90ZW1wbGF0ZXMvbGVhZmxldC5hd2Vzb21lLnJvdGF0ZS5jc3MiLz4KICAgIDxzdHlsZT5odG1sLCBib2R5IHt3aWR0aDogMTAwJTtoZWlnaHQ6IDEwMCU7bWFyZ2luOiAwO3BhZGRpbmc6IDA7fTwvc3R5bGU+CiAgICA8c3R5bGU+I21hcCB7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7Ym90dG9tOjA7cmlnaHQ6MDtsZWZ0OjA7fTwvc3R5bGU+CiAgICAKICAgICAgICAgICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwKICAgICAgICAgICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgICAgICAgICAgPHN0eWxlPgogICAgICAgICAgICAgICAgI21hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCB7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgbGVmdDogMC4wJTsKICAgICAgICAgICAgICAgICAgICB0b3A6IDAuMCU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgCjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvbGl1bS1tYXAiIGlkPSJtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgiID48L2Rpdj4KICAgICAgICAKPC9ib2R5Pgo8c2NyaXB0PiAgICAKICAgIAogICAgICAgICAgICB2YXIgbWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4ID0gTC5tYXAoCiAgICAgICAgICAgICAgICAibWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4IiwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjZW50ZXI6IFs0My42NTM0ODE3LCAtNzkuMzgzOTM0N10sCiAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICAgICAgICAgICAgICB6b29tOiAxMCwKICAgICAgICAgICAgICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBwcmVmZXJDYW52YXM6IGZhbHNlLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwoKICAgICAgICAgICAgCgogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyXzE5ZGE5ZmMzYzZiMDRhMGE4OGMwZjdlMzhkZDY0MTBhID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAiaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmciLAogICAgICAgICAgICAgICAgeyJhdHRyaWJ1dGlvbiI6ICJEYXRhIGJ5IFx1MDAyNmNvcHk7IFx1MDAzY2EgaHJlZj1cImh0dHA6Ly9vcGVuc3RyZWV0bWFwLm9yZ1wiXHUwMDNlT3BlblN0cmVldE1hcFx1MDAzYy9hXHUwMDNlLCB1bmRlciBcdTAwM2NhIGhyZWY9XCJodHRwOi8vd3d3Lm9wZW5zdHJlZXRtYXAub3JnL2NvcHlyaWdodFwiXHUwMDNlT0RiTFx1MDAzYy9hXHUwMDNlLiIsICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwgIm1heE5hdGl2ZVpvb20iOiAxOCwgIm1heFpvb20iOiAxOCwgIm1pblpvb20iOiAwLCAibm9XcmFwIjogZmFsc2UsICJvcGFjaXR5IjogMSwgInN1YmRvbWFpbnMiOiAiYWJjIiwgInRtcyI6IGZhbHNlfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTQ5YTMyZjFlYzZjNDljYWFjMmFkMTgzYzhmYjBhNGYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LCAtNzkuMzI5NjU2NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hZTBhYjMzYmFiYjc0OTRlYWQyZWRlMzNiNWM2OWUxOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDM4NDk2OWZjMjZhNDI3M2JkY2VmYTIyYjY2ZTIwMjMgPSAkKGA8ZGl2IGlkPSJodG1sX2QzODQ5NjlmYzI2YTQyNzNiZGNlZmEyMmI2NmUyMDIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrd29vZHMsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYWUwYWIzM2JhYmI3NDk0ZWFkMmVkZTMzYjVjNjllMTguc2V0Q29udGVudChodG1sX2QzODQ5NjlmYzI2YTQyNzNiZGNlZmEyMmI2NmUyMDIzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81NDlhMzJmMWVjNmM0OWNhYWMyYWQxODNjOGZiMGE0Zi5iaW5kUG9wdXAocG9wdXBfYWUwYWIzM2JhYmI3NDk0ZWFkMmVkZTMzYjVjNjllMTgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA1YWEyOWY2MDVkOTQ4NGE5Y2Y4MjY4ZDIzMjA3ZjM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LCAtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYjYyNWY1ODI4ZjY1NDQ0YWI0OTk3ZTRkOTFmNmJkNmIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2FiMDdkMDRjNjM4NDQwODFhMzdjZTE0OGUzZThiMjU5ID0gJChgPGRpdiBpZD0iaHRtbF9hYjA3ZDA0YzYzODQ0MDgxYTM3Y2UxNDhlM2U4YjI1OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VmljdG9yaWEgVmlsbGFnZSwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iNjI1ZjU4MjhmNjU0NDRhYjQ5OTdlNGQ5MWY2YmQ2Yi5zZXRDb250ZW50KGh0bWxfYWIwN2QwNGM2Mzg0NDA4MWEzN2NlMTQ4ZTNlOGIyNTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzA1YWEyOWY2MDVkOTQ4NGE5Y2Y4MjY4ZDIzMjA3ZjM0LmJpbmRQb3B1cChwb3B1cF9iNjI1ZjU4MjhmNjU0NDRhYjQ5OTdlNGQ5MWY2YmQ2YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWY0OWM3NjQyNjQ4NDQwZmJmY2VhODEyOGMyYjg0YTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTQyNTk5LCAtNzkuMzYwNjM1OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81NmM3NTM3MGJmNTM0MmY1YTQxNTIwNWZhMGQyY2U1YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2I4ODI0OTc2YjI5NDc0NWFkNmNjZWJiYzJlNGI2MGQgPSAkKGA8ZGl2IGlkPSJodG1sX2NiODgyNDk3NmIyOTQ3NDVhZDZjY2ViYmMyZTRiNjBkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SZWdlbnQgUGFyaywgSGFyYm91cmZyb250LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzU2Yzc1MzcwYmY1MzQyZjVhNDE1MjA1ZmEwZDJjZTViLnNldENvbnRlbnQoaHRtbF9jYjg4MjQ5NzZiMjk0NzQ1YWQ2Y2NlYmJjMmU0YjYwZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWY0OWM3NjQyNjQ4NDQwZmJmY2VhODEyOGMyYjg0YTAuYmluZFBvcHVwKHBvcHVwXzU2Yzc1MzcwYmY1MzQyZjVhNDE1MjA1ZmEwZDJjZTViKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZTg1N2MxNzUwYzE0NGJlYWUwZWNmZjM3MTJhNDQzYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwgLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jNzRmMDM0MmY3NTI0ZjYxYTJiNzA0ODk2OTc3ZmZjYSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzc0ZjAzNDJmNzUyNGY2MWEyYjcwNDg5Njk3N2ZmY2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIE1hbm9yLCBMYXdyZW5jZSBIZWlnaHRzLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1LnNldENvbnRlbnQoaHRtbF9jNzRmMDM0MmY3NTI0ZjYxYTJiNzA0ODk2OTc3ZmZjYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGU4NTdjMTc1MGMxNDRiZWFlMGVjZmYzNzEyYTQ0M2IuYmluZFBvcHVwKHBvcHVwX2Q1NGQyZThjYWIyNjQzYmFhYjA1MzVlNGM4OTkyMzg1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85NjZlMDIyY2YxYTg0OWQzYjlmMTI0NTliNTNiMmE0ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjMwMTUsIC03OS4zODk0OTM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mZWEzZWU0OWRkNzY0YzcyYjFhNmIzM2FkOTEwYzVlNSA9ICQoYDxkaXYgaWQ9Imh0bWxfZmVhM2VlNDlkZDc2NGM3MmIxYTZiMzNhZDkxMGM1ZTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlF1ZWVuJiMzOTtzIFBhcmssIE9udGFyaW8gUHJvdmluY2lhbCBHb3Zlcm5tZW50LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlLnNldENvbnRlbnQoaHRtbF9mZWEzZWU0OWRkNzY0YzcyYjFhNmIzM2FkOTEwYzVlNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTY2ZTAyMmNmMWE4NDlkM2I5ZjEyNDU5YjUzYjJhNGQuYmluZFBvcHVwKHBvcHVwXzFjMDI3MDAwNmE0YzQ5ODM5M2JhYTFmZGY2MzJhODRlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MzcwYmZiNjQyYzg0MmY1OWQ4YzI1YWZhMmQ3ODI1NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Nzg1NTYsIC03OS41MzIyNDI0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMGYxNmU1YTJhOWQ0NGQyNmExOTY1MTE2YjRmNjhlMWYgPSAkKGA8ZGl2IGlkPSJodG1sXzBmMTZlNWEyYTlkNDRkMjZhMTk2NTExNmI0ZjY4ZTFmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Jc2xpbmd0b24gQXZlbnVlLCBIdW1iZXIgVmFsbGV5IFZpbGxhZ2UsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYS5zZXRDb250ZW50KGh0bWxfMGYxNmU1YTJhOWQ0NGQyNmExOTY1MTE2YjRmNjhlMWYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzUzNzBiZmI2NDJjODQyZjU5ZDhjMjVhZmEyZDc4MjU2LmJpbmRQb3B1cChwb3B1cF8yMGVmZDg2ODc5ODc0ZDdlOTVkNTIzNTJlOTdmYjZjYSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjVjYWU1MTAwMmNmNDMyNjk4NTJmZWNlMWJhNWI2OGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My44MDY2ODYyOTk5OTk5OTYsIC03OS4xOTQzNTM0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zODAyYTEyNWFkYWI0ZGUzYWRkOWQ0OTE4YTA2MGQ3NCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2M0NTE4Y2VhOTYyNGY3YmEwM2ViNTk4YzhhOTg5ZjIgPSAkKGA8ZGl2IGlkPSJodG1sX2NjNDUxOGNlYTk2MjRmN2JhMDNlYjU5OGM4YTk4OWYyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NYWx2ZXJuLCBSb3VnZSwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzgwMmExMjVhZGFiNGRlM2FkZDlkNDkxOGEwNjBkNzQuc2V0Q29udGVudChodG1sX2NjNDUxOGNlYTk2MjRmN2JhMDNlYjU5OGM4YTk4OWYyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iNWNhZTUxMDAyY2Y0MzI2OTg1MmZlY2UxYmE1YjY4Yy5iaW5kUG9wdXAocG9wdXBfMzgwMmExMjVhZGFiNGRlM2FkZDlkNDkxOGEwNjBkNzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q1ZWZmODExOGQwODRmYjE4ZDE2ZjRlMzkwMTVhYWQyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ1OTA1Nzk5OTk5OTk2LCAtNzkuMzUyMTg4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzEyMGQyMzQ5ZWE4YzQwMzI5ZWQ5MzJmZTMwNzZjNDEyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zY2Y1Yjk3M2IzNzQ0ZDBmYTM0MWM5NGEzYjExMWY3OSA9ICQoYDxkaXYgaWQ9Imh0bWxfM2NmNWI5NzNiMzc0NGQwZmEzNDFjOTRhM2IxMTFmNzkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvbiBNaWxscywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xMjBkMjM0OWVhOGM0MDMyOWVkOTMyZmUzMDc2YzQxMi5zZXRDb250ZW50KGh0bWxfM2NmNWI5NzNiMzc0NGQwZmEzNDFjOTRhM2IxMTFmNzkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q1ZWZmODExOGQwODRmYjE4ZDE2ZjRlMzkwMTVhYWQyLmJpbmRQb3B1cChwb3B1cF8xMjBkMjM0OWVhOGM0MDMyOWVkOTMyZmUzMDc2YzQxMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGNjZmM5MDQxNWQ1NDk3MzhiOTI5MGNiZmJkMzFmNGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDYzOTcyLCAtNzkuMzA5OTM3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I4MDBhZDVmZDVmODRkNzdiMDM5YWI1ZTk5MTZlZDAwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zNTVhMzhjZTFlYjM0ZTk2YWU3NWNkMjk0NmZiODljNCA9ICQoYDxkaXYgaWQ9Imh0bWxfMzU1YTM4Y2UxZWIzNGU5NmFlNzVjZDI5NDZmYjg5YzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlBhcmt2aWV3IEhpbGwsIFdvb2RiaW5lIEdhcmRlbnMsIEVhc3QgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iODAwYWQ1ZmQ1Zjg0ZDc3YjAzOWFiNWU5OTE2ZWQwMC5zZXRDb250ZW50KGh0bWxfMzU1YTM4Y2UxZWIzNGU5NmFlNzVjZDI5NDZmYjg5YzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RjY2ZjOTA0MTVkNTQ5NzM4YjkyOTBjYmZiZDMxZjRjLmJpbmRQb3B1cChwb3B1cF9iODAwYWQ1ZmQ1Zjg0ZDc3YjAzOWFiNWU5OTE2ZWQwMCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGE3NzI5OGJkMzk0NGUwNmI5YmIxZDZjYzYwZDU3NmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTcxNjE4LCAtNzkuMzc4OTM3MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfM2NiN2VkMWZkZjg2NGZlZDk4MTIwNmI3Mzk5M2M5NTcgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRmYzI0NWJjZDk5MTRlNmE5M2UyMmFiNWIyOTY2NjMyID0gJChgPGRpdiBpZD0iaHRtbF80ZmMyNDViY2Q5OTE0ZTZhOTNlMjJhYjViMjk2NjYzMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2FyZGVuIERpc3RyaWN0LCBSeWVyc29uLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNjYjdlZDFmZGY4NjRmZWQ5ODEyMDZiNzM5OTNjOTU3LnNldENvbnRlbnQoaHRtbF80ZmMyNDViY2Q5OTE0ZTZhOTNlMjJhYjViMjk2NjYzMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGE3NzI5OGJkMzk0NGUwNmI5YmIxZDZjYzYwZDU3NmYuYmluZFBvcHVwKHBvcHVwXzNjYjdlZDFmZGY4NjRmZWQ5ODEyMDZiNzM5OTNjOTU3KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZGIwZTEwOThjN2I0YzRmYjRmNzEwYWQxM2I1MmFhZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTU3NywgLTc5LjQ0NTA3MjU5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzljMThjMWRiMTUxYzRlMTNhOWM5MDlmZDM4MzRlN2U2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kNTcyMWNlNzQxNTA0ZWI4OGJkMmUxY2E1MTM4M2NmZCA9ICQoYDxkaXYgaWQ9Imh0bWxfZDU3MjFjZTc0MTUwNGViODhiZDJlMWNhNTEzODNjZmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdsZW5jYWlybiwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85YzE4YzFkYjE1MWM0ZTEzYTljOTA5ZmQzODM0ZTdlNi5zZXRDb250ZW50KGh0bWxfZDU3MjFjZTc0MTUwNGViODhiZDJlMWNhNTEzODNjZmQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdkYjBlMTA5OGM3YjRjNGZiNGY3MTBhZDEzYjUyYWFkLmJpbmRQb3B1cChwb3B1cF85YzE4YzFkYjE1MWM0ZTEzYTljOTA5ZmQzODM0ZTdlNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDI1MDJhNzE5ZTgzNDk5NDgzNjZjNWRlZmExYTkyZTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTA5NDMyLCAtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjUzMTJkMjEyZDBlNDdjYzg5ZGUzZTljZGYxZTIyYjkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2Y2OGU1ZTBjNTBhNjQ0MzRhYjViNDQ5ZThmNGIyODJhID0gJChgPGRpdiBpZD0iaHRtbF9mNjhlNWUwYzUwYTY0NDM0YWI1YjQ0OWU4ZjRiMjgyYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdCBEZWFuZSBQYXJrLCBQcmluY2VzcyBHYXJkZW5zLCBNYXJ0aW4gR3JvdmUsIElzbGluZ3RvbiwgQ2xvdmVyZGFsZSwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y1MzEyZDIxMmQwZTQ3Y2M4OWRlM2U5Y2RmMWUyMmI5LnNldENvbnRlbnQoaHRtbF9mNjhlNWUwYzUwYTY0NDM0YWI1YjQ0OWU4ZjRiMjgyYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDI1MDJhNzE5ZTgzNDk5NDgzNjZjNWRlZmExYTkyZTQuYmluZFBvcHVwKHBvcHVwX2Y1MzEyZDIxMmQwZTQ3Y2M4OWRlM2U5Y2RmMWUyMmI5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82ODE5ODg2ZDg3NzQ0ZTU4YjVlYzkzNmM0OTRhZmZhYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4NDUzNTEsIC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZmU0N2UxYjFlMTM0MjBjYjg1YjgxNDQ5ODdkNTkwNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfM2FlYjdlMzgwNWQ3NDI1MmJiNTU3M2U3OTE0MmY4NjkgPSAkKGA8ZGl2IGlkPSJodG1sXzNhZWI3ZTM4MDVkNzQyNTJiYjU1NzNlNzkxNDJmODY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZSBIaWxsLCBQb3J0IFVuaW9uLCBIaWdobGFuZCBDcmVlaywgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmZlNDdlMWIxZTEzNDIwY2I4NWI4MTQ0OTg3ZDU5MDUuc2V0Q29udGVudChodG1sXzNhZWI3ZTM4MDVkNzQyNTJiYjU1NzNlNzkxNDJmODY5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82ODE5ODg2ZDg3NzQ0ZTU4YjVlYzkzNmM0OTRhZmZhYS5iaW5kUG9wdXAocG9wdXBfMmZlNDdlMWIxZTEzNDIwY2I4NWI4MTQ0OTg3ZDU5MDUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwZjc0NjgzOTBlMTQzMmNhYTBiZTU3NjNhMjc1NDQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODk5NzAwMDAwMDEsIC03OS4zNDA5MjNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZmNjZTMyYmQwMjc2NDYyZmE3NGIyZDMyMzliODYyMDIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI0ZmE3ZTM1MzVlMjRjZmZiYmQ4MDY3NTJlMDRmNTYyID0gJChgPGRpdiBpZD0iaHRtbF8yNGZhN2UzNTM1ZTI0Y2ZmYmJkODA2NzUyZTA0ZjU2MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG9uIE1pbGxzLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2ZjY2UzMmJkMDI3NjQ2MmZhNzRiMmQzMjM5Yjg2MjAyLnNldENvbnRlbnQoaHRtbF8yNGZhN2UzNTM1ZTI0Y2ZmYmJkODA2NzUyZTA0ZjU2Mik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjBmNzQ2ODM5MGUxNDMyY2FhMGJlNTc2M2EyNzU0NDUuYmluZFBvcHVwKHBvcHVwX2ZjY2UzMmJkMDI3NjQ2MmZhNzRiMmQzMjM5Yjg2MjAyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83ZWIxYWQyMzA5NDU0ZDhmYTdhMmQxNTU4ZmFjMjdiNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NTM0MzkwMDAwMDAwNSwgLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTY3OWY2MzQyNDg5NDE5MDgwMjQ1ZjdhMzExNTVhMTMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2NjZGQxZGVlNmZhMDQ3MDFhODNiOTg2ZmRhNDU5YjRlID0gJChgPGRpdiBpZD0iaHRtbF9jY2RkMWRlZTZmYTA0NzAxYTgzYjk4NmZkYTQ1OWI0ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29vZGJpbmUgSGVpZ2h0cywgRWFzdCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk2NzlmNjM0MjQ4OTQxOTA4MDI0NWY3YTMxMTU1YTEzLnNldENvbnRlbnQoaHRtbF9jY2RkMWRlZTZmYTA0NzAxYTgzYjk4NmZkYTQ1OWI0ZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfN2ViMWFkMjMwOTQ1NGQ4ZmE3YTJkMTU1OGZhYzI3YjcuYmluZFBvcHVwKHBvcHVwXzk2NzlmNjM0MjQ4OTQxOTA4MDI0NWY3YTMxMTU1YTEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xZmQ4MmU4MDVkNWU0ZDNlYjExYmU2ODU4YmE2NjVkNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MTQ5MzksIC03OS4zNzU0MTc5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yN2NkNGViMjA0NjU0YmE1ODhmMzQ0OGEwNzRhNDhiMSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjdjZDRlYjIwNDY1NGJhNTg4ZjM0NDhhMDc0YTQ4YjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0LiBKYW1lcyBUb3duLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1LnNldENvbnRlbnQoaHRtbF8yN2NkNGViMjA0NjU0YmE1ODhmMzQ0OGEwNzRhNDhiMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWZkODJlODA1ZDVlNGQzZWIxMWJlNjg1OGJhNjY1ZDcuYmluZFBvcHVwKHBvcHVwX2MwNDBlN2YwYTViMTQ4N2VhYzhlYjk1NzU1YmNhNjM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iZjEwNGE0Y2YyOGM0YjI0ODg0NWJkM2QyZjI2Y2MzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5Mzc4MTMsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xNmY1ZmI1ZmUzOGQ0NjI4ODRhNDBhZmEyODAzMWUyOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmM5NmYwZDRkYTU1NDc3Mjk4ZDVhMTM4YTVmY2NiNDIgPSAkKGA8ZGl2IGlkPSJodG1sXzZjOTZmMGQ0ZGE1NTQ3NzI5OGQ1YTEzOGE1ZmNjYjQyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1ld29vZC1DZWRhcnZhbGUsIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMTZmNWZiNWZlMzhkNDYyODg0YTQwYWZhMjgwMzFlMjkuc2V0Q29udGVudChodG1sXzZjOTZmMGQ0ZGE1NTQ3NzI5OGQ1YTEzOGE1ZmNjYjQyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iZjEwNGE0Y2YyOGM0YjI0ODg0NWJkM2QyZjI2Y2MzOC5iaW5kUG9wdXAocG9wdXBfMTZmNWZiNWZlMzhkNDYyODg0YTQwYWZhMjgwMzFlMjkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA0NjlkMjhiOTEzNDRmYzRiODY2NmFiZWFjM2QxZThlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQzNTE1MiwgLTc5LjU3NzIwMDc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VlY2JiMTE2ODdhNzQ0ZDViODc4M2JkOGYxMTE2MjM3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YzExOTc0MTEzZWY0MjRiYWVlY2FmZTYyYWU3ZTIxNCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWMxMTk3NDExM2VmNDI0YmFlZWNhZmU2MmFlN2UyMTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVyaW5nYXRlLCBCbG9vcmRhbGUgR2FyZGVucywgT2xkIEJ1cm5oYW10aG9ycGUsIE1hcmtsYW5kIFdvb2QsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lZWNiYjExNjg3YTc0NGQ1Yjg3ODNiZDhmMTExNjIzNy5zZXRDb250ZW50KGh0bWxfNWMxMTk3NDExM2VmNDI0YmFlZWNhZmU2MmFlN2UyMTQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzA0NjlkMjhiOTEzNDRmYzRiODY2NmFiZWFjM2QxZThlLmJpbmRQb3B1cChwb3B1cF9lZWNiYjExNjg3YTc0NGQ1Yjg3ODNiZDhmMTExNjIzNykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWM1OTA2MDNmOWY5NGZlYjgwOGRkNjIwMzUwOTgxZDMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NjM1NzI2LCAtNzkuMTg4NzExNV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83MDc0ZWYyNzI1NWI0ZDc5OTVlYjg1MzBiZDYxZjk3YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjY2NGExYmFlMDY5NGQ4M2JiYTY4ZjQyYmQ0ZDM5ZDkgPSAkKGA8ZGl2IGlkPSJodG1sXzY2NjRhMWJhZTA2OTRkODNiYmE2OGY0MmJkNGQzOWQ5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HdWlsZHdvb2QsIE1vcm5pbmdzaWRlLCBXZXN0IEhpbGwsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzcwNzRlZjI3MjU1YjRkNzk5NWViODUzMGJkNjFmOTdiLnNldENvbnRlbnQoaHRtbF82NjY0YTFiYWUwNjk0ZDgzYmJhNjhmNDJiZDRkMzlkOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYWM1OTA2MDNmOWY5NGZlYjgwOGRkNjIwMzUwOTgxZDMuYmluZFBvcHVwKHBvcHVwXzcwNzRlZjI3MjU1YjRkNzk5NWViODUzMGJkNjFmOTdiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNjllM2I2YmI1NGU0OTM0OGNmZGYyOTZjYmQxZDY5YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3NjM1NzM5OTk5OTk5LCAtNzkuMjkzMDMxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iMmI1MDZlOTY3MDU0MTI0OTRhMGYyZWEyZGRjOGIxYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmNjMzdmYzBlYWIzNDRlZWFmNmJmOGJlMzJjN2YxYmEgPSAkKGA8ZGl2IGlkPSJodG1sXzZjYzM3ZmMwZWFiMzQ0ZWVhZjZiZjhiZTMyYzdmMWJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcywgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2IyYjUwNmU5NjcwNTQxMjQ5NGEwZjJlYTJkZGM4YjFjLnNldENvbnRlbnQoaHRtbF82Y2MzN2ZjMGVhYjM0NGVlYWY2YmY4YmUzMmM3ZjFiYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTY5ZTNiNmJiNTRlNDkzNDhjZmRmMjk2Y2JkMWQ2OWIuYmluZFBvcHVwKHBvcHVwX2IyYjUwNmU5NjcwNTQxMjQ5NGEwZjJlYTJkZGM4YjFjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lOTA5ZjUxYTNlZDI0NTQ5OGU2NzE5MWQxYjA5Zjk0ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NDc3MDc5OTk5OTk5NiwgLTc5LjM3MzMwNjRdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2IgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzMxYTQ2OTExZjZlZTRlNTM5ODljNjI1ZGQ3MzVmOTU4ID0gJChgPGRpdiBpZD0iaHRtbF8zMWE0NjkxMWY2ZWU0ZTUzOTg5YzYyNWRkNzM1Zjk1OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVyY3p5IFBhcmssIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2Iuc2V0Q29udGVudChodG1sXzMxYTQ2OTExZjZlZTRlNTM5ODljNjI1ZGQ3MzVmOTU4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lOTA5ZjUxYTNlZDI0NTQ5OGU2NzE5MWQxYjA5Zjk0ZS5iaW5kUG9wdXAocG9wdXBfNzUzOTBhNDMwNmRkNDFmZWFhM2U5NWJiNGY5NmY3M2IpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzJlNWQ3ZmQzYjNlOTQ2MmFiOTU1NWQ4MzE0ODM2NjdhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg5MDI1NiwgLTc5LjQ1MzUxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zYTIzMDk1YzJjNDQ0OWIwODM0MGM2MDYxNGY0MGRhOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjUwMzM5MDFkZWM4NDRmNWJhN2EwNGMyZmNjMmI0NzkgPSAkKGA8ZGl2IGlkPSJodG1sX2Y1MDMzOTAxZGVjODQ0ZjViYTdhMDRjMmZjYzJiNDc5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DYWxlZG9uaWEtRmFpcmJhbmtzLCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNhMjMwOTVjMmM0NDQ5YjA4MzQwYzYwNjE0ZjQwZGE5LnNldENvbnRlbnQoaHRtbF9mNTAzMzkwMWRlYzg0NGY1YmE3YTA0YzJmY2MyYjQ3OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMmU1ZDdmZDNiM2U5NDYyYWI5NTU1ZDgzMTQ4MzY2N2EuYmluZFBvcHVwKHBvcHVwXzNhMjMwOTVjMmM0NDQ5YjA4MzQwYzYwNjE0ZjQwZGE5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYzlhMTI0ZjlkNmM0NmM2YmZjNWUyNjliMWFjZmZkMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDk5MjEsIC03OS4yMTY5MTc0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80YTY4ZjgzZTlkMjY0ZjdlODliMGFlODVmZDA0MDA3ZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMGFiYmY2NWNkNGZhNDRiN2ExODIzNTkzODk2Y2U3MzAgPSAkKGA8ZGl2IGlkPSJodG1sXzBhYmJmNjVjZDRmYTQ0YjdhMTgyMzU5Mzg5NmNlNzMwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb2J1cm4sIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzRhNjhmODNlOWQyNjRmN2U4OWIwYWU4NWZkMDQwMDdlLnNldENvbnRlbnQoaHRtbF8wYWJiZjY1Y2Q0ZmE0NGI3YTE4MjM1OTM4OTZjZTczMCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYmM5YTEyNGY5ZDZjNDZjNmJmYzVlMjY5YjFhY2ZmZDIuYmluZFBvcHVwKHBvcHVwXzRhNjhmODNlOWQyNjRmN2U4OWIwYWU4NWZkMDQwMDdlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNTQyNzVjYmVjOTA0NmM0YTNmZGQ3OGMzNzAxNmU5MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTA2MDQsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IzZjllZTg2YTg2MDQ5YzdhNDA1Y2VhM2RmZmI4OWVjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85NzY0NTAzNmRkNGY0NmIwOWQ1OGVjOWUwZjg0NmQxMyA9ICQoYDxkaXYgaWQ9Imh0bWxfOTc2NDUwMzZkZDRmNDZiMDlkNThlYzllMGY4NDZkMTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxlYXNpZGUsIEVhc3QgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iM2Y5ZWU4NmE4NjA0OWM3YTQwNWNlYTNkZmZiODllYy5zZXRDb250ZW50KGh0bWxfOTc2NDUwMzZkZDRmNDZiMDlkNThlYzllMGY4NDZkMTMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzE1NDI3NWNiZWM5MDQ2YzRhM2ZkZDc4YzM3MDE2ZTkzLmJpbmRQb3B1cChwb3B1cF9iM2Y5ZWU4NmE4NjA0OWM3YTQwNWNlYTNkZmZiODllYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzYxYzNjOWY0ZGYzNDY1MWJmMWIzYmU5NDZlMDBhYTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTc5NTI0LCAtNzkuMzg3MzgyNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jMmI5ZDI5NWNmMzY0MWRiOTAwODFmMWYxNmFlNTc0YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWVlNTA4NGEzYjRiNDU3N2I2YTYwMjEyNGE0NjU1MzggPSAkKGA8ZGl2IGlkPSJodG1sXzFlZTUwODRhM2I0YjQ1NzdiNmE2MDIxMjRhNDY1NTM4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZW50cmFsIEJheSBTdHJlZXQsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYzJiOWQyOTVjZjM2NDFkYjkwMDgxZjFmMTZhZTU3NGIuc2V0Q29udGVudChodG1sXzFlZTUwODRhM2I0YjQ1NzdiNmE2MDIxMjRhNDY1NTM4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8zNjFjM2M5ZjRkZjM0NjUxYmYxYjNiZTk0NmUwMGFhMC5iaW5kUG9wdXAocG9wdXBfYzJiOWQyOTVjZjM2NDFkYjkwMDgxZjFmMTZhZTU3NGIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NlMTI4YzQwNjZlNjQ4ZmRhODkxNzFjMTEwNTRhZmM4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY5NTQyLCAtNzkuNDIyNTYzN10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzM2ZTAzODMxMGE5NDkzZDg0M2Q0NTg1ZTU5Y2VkMWUgPSAkKGA8ZGl2IGlkPSJodG1sXzMzNmUwMzgzMTBhOTQ5M2Q4NDNkNDU4NWU1OWNlZDFlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DaHJpc3RpZSwgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYS5zZXRDb250ZW50KGh0bWxfMzM2ZTAzODMxMGE5NDkzZDg0M2Q0NTg1ZTU5Y2VkMWUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2NlMTI4YzQwNjZlNjQ4ZmRhODkxNzFjMTEwNTRhZmM4LmJpbmRQb3B1cChwb3B1cF83N2E2M2ExMTg5NTk0MTg2Yjk0OWQ3ODE5YzRhMjlhYSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmM2ZTRhZTlkMmFlNDExN2FkODkyNDFjZGVlYWMzYzQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzMxMzYsIC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84NmE2MTBiY2I1NWY0ODE2OGEyZDJjN2I1OTkwMGRlYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMDBiNzI4NWYyMTc2NDA4NGIxMDhmODE4NTdmODU0ZjkgPSAkKGA8ZGl2IGlkPSJodG1sXzAwYjcyODVmMjE3NjQwODRiMTA4ZjgxODU3Zjg1NGY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5DZWRhcmJyYWUsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg2YTYxMGJjYjU1ZjQ4MTY4YTJkMmM3YjU5OTAwZGVhLnNldENvbnRlbnQoaHRtbF8wMGI3Mjg1ZjIxNzY0MDg0YjEwOGY4MTg1N2Y4NTRmOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMmM2ZTRhZTlkMmFlNDExN2FkODkyNDFjZGVlYWMzYzQuYmluZFBvcHVwKHBvcHVwXzg2YTYxMGJjYjU1ZjQ4MTY4YTJkMmM3YjU5OTAwZGVhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82Y2ZlY2NkMDNhZmY0Nzg1OTllNTRmOTllNDliODExMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwMzc2MjIsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YzY0ZDc1ZDliZWI0ODdiOWI2ZDdmMjEzZDA2Y2NjMSA9ICQoYDxkaXYgaWQ9Imh0bWxfNWM2NGQ3NWQ5YmViNDg3YjliNmQ3ZjIxM2QwNmNjYzEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpbGxjcmVzdCBWaWxsYWdlLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiLnNldENvbnRlbnQoaHRtbF81YzY0ZDc1ZDliZWI0ODdiOWI2ZDdmMjEzZDA2Y2NjMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNmNmZWNjZDAzYWZmNDc4NTk5ZTU0Zjk5ZTQ5YjgxMTMuYmluZFBvcHVwKHBvcHVwX2I4YTkxZmZhODk5YzQxY2ViNTE2MDBjZjE5OGJjMDBiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wM2Q1MjFkYmI5N2Y0NjljYmY2MTZhMzFhZmE5MTY3MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NDMyODMsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ODA4NjY3NjQ4ODI0ZmM3YWEyODViNWM5ZmFiN2Q5MSA9ICQoYDxkaXYgaWQ9Imh0bWxfOTgwODY2NzY0ODgyNGZjN2FhMjg1YjVjOWZhYjdkOTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJhdGh1cnN0IE1hbm9yLCBXaWxzb24gSGVpZ2h0cywgRG93bnN2aWV3IE5vcnRoLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliLnNldENvbnRlbnQoaHRtbF85ODA4NjY3NjQ4ODI0ZmM3YWEyODViNWM5ZmFiN2Q5MSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDNkNTIxZGJiOTdmNDY5Y2JmNjE2YTMxYWZhOTE2NzEuYmluZFBvcHVwKHBvcHVwXzlhZWQ3ZWQ5Zjk3YTRhMDc4ZjhmNTgzNDFiYzAzZjliKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jNDJiYmEwNzUzZDQ0ZDI1YWQyODMxYmU3ZDEwYmJjZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNTM2ODksIC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hNDMzZmY1MTk4OTU0ZGVmOWViMzhhNTVhOGRkODZjZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZmRkMjIzNjgxYTQ0NDNiNmExYTQzYjM5MTI1MTIwYjMgPSAkKGA8ZGl2IGlkPSJodG1sX2ZkZDIyMzY4MWE0NDQzYjZhMWE0M2IzOTEyNTEyMGIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaG9ybmNsaWZmZSBQYXJrLCBFYXN0IFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTQzM2ZmNTE5ODk1NGRlZjllYjM4YTU1YThkZDg2Y2Quc2V0Q29udGVudChodG1sX2ZkZDIyMzY4MWE0NDQzYjZhMWE0M2IzOTEyNTEyMGIzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jNDJiYmEwNzUzZDQ0ZDI1YWQyODMxYmU3ZDEwYmJjZS5iaW5kUG9wdXAocG9wdXBfYTQzM2ZmNTE5ODk1NGRlZjllYjM4YTU1YThkZDg2Y2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzU0YjVhNjdmZjk1MTQxMWRiZjE2NTRhM2YxNTJmN2JmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUwNTcxMjAwMDAwMDEsIC03OS4zODQ1Njc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzY5M2U5MDZlOTE2MDQ3MTVhMzkzMTNiODIzNTc3N2I4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jMmRlODlmZjlhNjM0ZGE4OGIyYTk5NGM0NTE5MDBlOSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzJkZTg5ZmY5YTYzNGRhODhiMmE5OTRjNDUxOTAwZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJpY2htb25kLCBBZGVsYWlkZSwgS2luZywgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF82OTNlOTA2ZTkxNjA0NzE1YTM5MzEzYjgyMzU3NzdiOC5zZXRDb250ZW50KGh0bWxfYzJkZTg5ZmY5YTYzNGRhODhiMmE5OTRjNDUxOTAwZTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzU0YjVhNjdmZjk1MTQxMWRiZjE2NTRhM2YxNTJmN2JmLmJpbmRQb3B1cChwb3B1cF82OTNlOTA2ZTkxNjA0NzE1YTM5MzEzYjgyMzU3NzdiOCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjZmOTNhYzljZTIwNDMyOWE0OWU5NDkwYTY1MzU4MmEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjkwMDUxMDAwMDAwMSwgLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWM1ZWU1OWM1ZGFiNDQzMTk4YmEzMDU4MmM5ZmU0MGUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiMTdjM2Y5M2M0NTRhOTFhNGM3MGM2ZGMyN2NkMjI5ID0gJChgPGRpdiBpZD0iaHRtbF80YjE3YzNmOTNjNDU0YTkxYTRjNzBjNmRjMjdjZDIyOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RHVmZmVyaW4sIERvdmVyY291cnQgVmlsbGFnZSwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2FjNWVlNTljNWRhYjQ0MzE5OGJhMzA1ODJjOWZlNDBlLnNldENvbnRlbnQoaHRtbF80YjE3YzNmOTNjNDU0YTkxYTRjNzBjNmRjMjdjZDIyOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjZmOTNhYzljZTIwNDMyOWE0OWU5NDkwYTY1MzU4MmEuYmluZFBvcHVwKHBvcHVwX2FjNWVlNTljNWRhYjQ0MzE5OGJhMzA1ODJjOWZlNDBlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zOGVkYzRlYmFiYTE0ZDI3YTI4NDIwYWJkM2EzNzE5YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NDczNDIsIC03OS4yMzk0NzYwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYWMyMzUxMWJjNjQyNDQyY2JmOTA3MmFhYWJkMjFjMWMgPSAkKGA8ZGl2IGlkPSJodG1sX2FjMjM1MTFiYzY0MjQ0MmNiZjkwNzJhYWFiZDIxYzFjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TY2FyYm9yb3VnaCBWaWxsYWdlLCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMC5zZXRDb250ZW50KGh0bWxfYWMyMzUxMWJjNjQyNDQyY2JmOTA3MmFhYWJkMjFjMWMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzM4ZWRjNGViYWJhMTRkMjdhMjg0MjBhYmQzYTM3MTliLmJpbmRQb3B1cChwb3B1cF85NmNlMjhlOGQ1ZWE0YjE1YmNjZTNiNjAwMzI0YTJiMCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmI3ZjZhOTA5ZTg5NGQzMTkxMjk4NDM4MTljMTBlMmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Nzg1MTc1LCAtNzkuMzQ2NTU1N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mMzA5M2YwMzZiODY0NWYxODNkYjA3ZWJhYWY1N2NiMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDllZjg4Y2JkNWZmNGRjOTgyNWQ3MzQxNjgyMzRmYzMgPSAkKGA8ZGl2IGlkPSJodG1sX2Q5ZWY4OGNiZDVmZjRkYzk4MjVkNzM0MTY4MjM0ZmMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5GYWlydmlldywgSGVucnkgRmFybSwgT3Jpb2xlLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2YzMDkzZjAzNmI4NjQ1ZjE4M2RiMDdlYmFhZjU3Y2IzLnNldENvbnRlbnQoaHRtbF9kOWVmODhjYmQ1ZmY0ZGM5ODI1ZDczNDE2ODIzNGZjMyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYmI3ZjZhOTA5ZTg5NGQzMTkxMjk4NDM4MTljMTBlMmQuYmluZFBvcHVwKHBvcHVwX2YzMDkzZjAzNmI4NjQ1ZjE4M2RiMDdlYmFhZjU3Y2IzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMjEwZmU1MTNkNDk0MGJmYjJiZjQ3MzA5MDM1MGM5YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2Nzk4MDMsIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82OThmZmI4MWZiYjI0ZGMzYmQyOGFhNjhiYzQzMzJjNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZGNjNDFiZWQxNTI4NGFkYTk4NGJjMTAwNTg3Mzk5MjUgPSAkKGA8ZGl2IGlkPSJodG1sX2RjYzQxYmVkMTUyODRhZGE5ODRiYzEwMDU4NzM5OTI1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aHdvb2QgUGFyaywgWW9yayBVbml2ZXJzaXR5LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY5OGZmYjgxZmJiMjRkYzNiZDI4YWE2OGJjNDMzMmM0LnNldENvbnRlbnQoaHRtbF9kY2M0MWJlZDE1Mjg0YWRhOTg0YmMxMDA1ODczOTkyNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjIxMGZlNTEzZDQ5NDBiZmIyYmY0NzMwOTAzNTBjOWEuYmluZFBvcHVwKHBvcHVwXzY5OGZmYjgxZmJiMjRkYzNiZDI4YWE2OGJjNDMzMmM0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MWRhOThiNmQ5OGQ0YmI4OWY5YTk2ZjFlMTkzYWM3YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4NTM0NywgLTc5LjMzODEwNjVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNlZmU1N2RmNTBjNjRiMTU5MTI0MjYzMTMzMmNhMmI1ID0gJChgPGRpdiBpZD0iaHRtbF8zZWZlNTdkZjUwYzY0YjE1OTEyNDI2MzEzMzJjYTJiNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RWFzdCBUb3JvbnRvLCBCcm9hZHZpZXcgTm9ydGggKE9sZCBFYXN0IFlvcmspLCBFYXN0IFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMuc2V0Q29udGVudChodG1sXzNlZmU1N2RmNTBjNjRiMTU5MTI0MjYzMTMzMmNhMmI1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MWRhOThiNmQ5OGQ0YmI4OWY5YTk2ZjFlMTkzYWM3Yy5iaW5kUG9wdXAocG9wdXBfMjE0MDdkZDU2ZGY4NDZiNWI0ZGE1ZjY1ZmMwMDJhMzMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmZTY4N2QwOTQwMDRiOTI4NDgyZTFiZTIyNDNmZjQ2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQwODE1NywgLTc5LjM4MTc1MjI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VmZjgxMzA4YjU3NDQzNWNiMGRhZjRiODRhNTcwZWQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84ZGM3MGViOTQwNDQ0Zjg1YmVjNzNmNzY0MzQwNDQ4NCA9ICQoYDxkaXYgaWQ9Imh0bWxfOGRjNzBlYjk0MDQ0NGY4NWJlYzczZjc2NDM0MDQ0ODQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhhcmJvdXJmcm9udCBFYXN0LCBVbmlvbiBTdGF0aW9uLCBUb3JvbnRvIElzbGFuZHMsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWZmODEzMDhiNTc0NDM1Y2IwZGFmNGI4NGE1NzBlZDQuc2V0Q29udGVudChodG1sXzhkYzcwZWI5NDA0NDRmODViZWM3M2Y3NjQzNDA0NDg0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZmU2ODdkMDk0MDA0YjkyODQ4MmUxYmUyMjQzZmY0Ni5iaW5kUG9wdXAocG9wdXBfZWZmODEzMDhiNTc0NDM1Y2IwZGFmNGI4NGE1NzBlZDQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdjZDZmMGUwOWRjNjQ3ZTE4MDg5OGU0MWE2MzMzOWQxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ3OTI2NzAwMDAwMDA2LCAtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjVlYmQxZjNlNWY5NDJhMmE4NzU5OTM2Y2FlMmJkZDYgPSAkKGA8ZGl2IGlkPSJodG1sXzY1ZWJkMWYzZTVmOTQyYTJhODc1OTkzNmNhZTJiZGQ2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MaXR0bGUgUG9ydHVnYWwsIFRyaW5pdHksIFdlc3QgVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMS5zZXRDb250ZW50KGh0bWxfNjVlYmQxZjNlNWY5NDJhMmE4NzU5OTM2Y2FlMmJkZDYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdjZDZmMGUwOWRjNjQ3ZTE4MDg5OGU0MWE2MzMzOWQxLmJpbmRQb3B1cChwb3B1cF83OTVhNjBkNGQ3MDk0MTA0YmEzMDdiNGVkMjgyMmZhMSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWVhMGJkZjNjZGIwNDhkMTk2MmRjNjVmMGQ5YzJmM2UgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLCAtNzkuMjYyMDI5NDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VjMDczMzcxMDJjNzQwMjNhNzU1ZDA3MTllOWYwYTM4ID0gJChgPGRpdiBpZD0iaHRtbF9lYzA3MzM3MTAyYzc0MDIzYTc1NWQwNzE5ZTlmMGEzOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2VubmVkeSBQYXJrLCBJb252aWV3LCBFYXN0IEJpcmNobW91bnQgUGFyaywgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEuc2V0Q29udGVudChodG1sX2VjMDczMzcxMDJjNzQwMjNhNzU1ZDA3MTllOWYwYTM4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xZWEwYmRmM2NkYjA0OGQxOTYyZGM2NWYwZDljMmYzZS5iaW5kUG9wdXAocG9wdXBfNjliZWMxNDNjYmE3NDg0OWI4MzFkNDc2ZTJhZjg5YWEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI3YWNmMzA0ZjFhMDQ2M2RiZDg0ZmE1MThkMmUzOWQ0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg2OTQ3MywgLTc5LjM4NTk3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84ZTMzYzk2ZWNiODQ0ZGU3YmYwNWFjNTI5ZDgxMzAzMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDEyMWFhNzQxYTkwNDFlZjgzYzZkNDk0YTc0ZDRiZjkgPSAkKGA8ZGl2IGlkPSJodG1sXzQxMjFhYTc0MWE5MDQxZWY4M2M2ZDQ5NGE3NGQ0YmY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CYXl2aWV3IFZpbGxhZ2UsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGUzM2M5NmVjYjg0NGRlN2JmMDVhYzUyOWQ4MTMwMzAuc2V0Q29udGVudChodG1sXzQxMjFhYTc0MWE5MDQxZWY4M2M2ZDQ5NGE3NGQ0YmY5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yN2FjZjMwNGYxYTA0NjNkYmQ4NGZhNTE4ZDJlMzlkNC5iaW5kUG9wdXAocG9wdXBfOGUzM2M5NmVjYjg0NGRlN2JmMDVhYzUyOWQ4MTMwMzApCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI3YThmZjRkZmRmYzQ2NDdhZmNmZTgwZGViOThkMTczID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM3NDczMjAwMDAwMDA0LCAtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTgzN2FhMDA1OTkzNDFjNWFkYzFmMWIxMjk2ZmYzNzkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzAyMjA1MTY2MmEwODQxYmY4ZGE4ZGE1YTM0ZmRjNWY2ID0gJChgPGRpdiBpZD0iaHRtbF8wMjIwNTE2NjJhMDg0MWJmOGRhOGRhNWEzNGZkYzVmNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk4MzdhYTAwNTk5MzQxYzVhZGMxZjFiMTI5NmZmMzc5LnNldENvbnRlbnQoaHRtbF8wMjIwNTE2NjJhMDg0MWJmOGRhOGRhNWEzNGZkYzVmNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjdhOGZmNGRmZGZjNDY0N2FmY2ZlODBkZWI5OGQxNzMuYmluZFBvcHVwKHBvcHVwXzk4MzdhYTAwNTk5MzQxYzVhZGMxZjFiMTI5NmZmMzc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lMTFmMjkyMzk5ZjI0NjlmODAxMDc1ZWQ0Yjc3YjM4NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3OTU1NzEsIC03OS4zNTIxODhdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOWQ0YmQ0MGMxYTVhNDdjNGJkZTY1MmRmZTdlNmIwYWMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzEyODYyYWE3NDEzMjQ1Y2FiNmNkZDFjOWM2MzUzMjA2ID0gJChgPGRpdiBpZD0iaHRtbF8xMjg2MmFhNzQxMzI0NWNhYjZjZGQxYzljNjM1MzIwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIERhbmZvcnRoIFdlc3QsIFJpdmVyZGFsZSwgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzlkNGJkNDBjMWE1YTQ3YzRiZGU2NTJkZmU3ZTZiMGFjLnNldENvbnRlbnQoaHRtbF8xMjg2MmFhNzQxMzI0NWNhYjZjZGQxYzljNjM1MzIwNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZTExZjI5MjM5OWYyNDY5ZjgwMTA3NWVkNGI3N2IzODQuYmluZFBvcHVwKHBvcHVwXzlkNGJkNDBjMWE1YTQ3YzRiZGU2NTJkZmU3ZTZiMGFjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMTAyYjhjMTAwYjU0NzU5ODQyM2EwNGEwZjM0NDQyZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzE3NjgsIC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mNzlhZTMzMGU3MDM0NDc3OGFkMDM0Njc0OGVjM2ZhMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfN2ZkMzJiNzFhNmFiNDA4YmEzYjE2YTExNDJmZWY1NDMgPSAkKGA8ZGl2IGlkPSJodG1sXzdmZDMyYjcxYTZhYjQwOGJhM2IxNmExMTQyZmVmNTQzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ub3JvbnRvIERvbWluaW9uIENlbnRyZSwgRGVzaWduIEV4Y2hhbmdlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y3OWFlMzMwZTcwMzQ0Nzc4YWQwMzQ2NzQ4ZWMzZmEzLnNldENvbnRlbnQoaHRtbF83ZmQzMmI3MWE2YWI0MDhiYTNiMTZhMTE0MmZlZjU0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTEwMmI4YzEwMGI1NDc1OTg0MjNhMDRhMGYzNDQ0MmQuYmluZFBvcHVwKHBvcHVwX2Y3OWFlMzMwZTcwMzQ0Nzc4YWQwMzQ2NzQ4ZWMzZmEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iNmU2ZmQwNGE3ZDY0YmNlODkxYzNjZjhiZjg4MTRhZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjg0NzIsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xN2FkMzQxZTk5OTk0MGM5ODEyNjA1ZjBmNjk0ZTBlZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMTYzOTYwMTI0YWE3NDYxMGJlYjQ1YjIzMGVmYWNmMGQgPSAkKGA8ZGl2IGlkPSJodG1sXzE2Mzk2MDEyNGFhNzQ2MTBiZWI0NWIyMzBlZmFjZjBkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ccm9ja3RvbiwgUGFya2RhbGUgVmlsbGFnZSwgRXhoaWJpdGlvbiBQbGFjZSwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzE3YWQzNDFlOTk5OTQwYzk4MTI2MDVmMGY2OTRlMGVmLnNldENvbnRlbnQoaHRtbF8xNjM5NjAxMjRhYTc0NjEwYmViNDViMjMwZWZhY2YwZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjZlNmZkMDRhN2Q2NGJjZTg5MWMzY2Y4YmY4ODE0YWYuYmluZFBvcHVwKHBvcHVwXzE3YWQzNDFlOTk5OTQwYzk4MTI2MDVmMGY2OTRlMGVmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YzMyY2Y1NzJkOTI0Njg2YWZmNzIyYzNhNzNiZmI4OSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMTExMTcwMDAwMDAwNCwgLTc5LjI4NDU3NzJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VlYWY2MmI1MWJjNTQwMTZiZmQ0ZWQwNGFjNTExMzMwID0gJChgPGRpdiBpZD0iaHRtbF9lZWFmNjJiNTFiYzU0MDE2YmZkNGVkMDRhYzUxMTMzMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R29sZGVuIE1pbGUsIENsYWlybGVhLCBPYWtyaWRnZSwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQuc2V0Q29udGVudChodG1sX2VlYWY2MmI1MWJjNTQwMTZiZmQ0ZWQwNGFjNTExMzMwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YzMyY2Y1NzJkOTI0Njg2YWZmNzIyYzNhNzNiZmI4OS5iaW5kUG9wdXAocG9wdXBfZTE4MjRjYzUyYTA0NDBjNDk3ZDFjYWM5ZDMwNWYzNjQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdiMzYxNzEyOWFlNDRhNWM5MTQ4ZjZjMDY4ZjU1ZmYyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDkwMiwgLTc5LjM3NDcxNDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcyZmNjMTE0YzIzNDQ3ZGE5ZjkyYjNiNmIxODEwOWVjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yMGMxY2ZiMTRhMzQ0NjgzYmE2ZGJiZGNiZjBiNWVkYiA9ICQoYDxkaXYgaWQ9Imh0bWxfMjBjMWNmYjE0YTM0NDY4M2JhNmRiYmRjYmYwYjVlZGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPllvcmsgTWlsbHMsIFNpbHZlciBIaWxscywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MmZjYzExNGMyMzQ0N2RhOWY5MmIzYjZiMTgxMDllYy5zZXRDb250ZW50KGh0bWxfMjBjMWNmYjE0YTM0NDY4M2JhNmRiYmRjYmYwYjVlZGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzdiMzYxNzEyOWFlNDRhNWM5MTQ4ZjZjMDY4ZjU1ZmYyLmJpbmRQb3B1cChwb3B1cF83MmZjYzExNGMyMzQ0N2RhOWY5MmIzYjZiMTgxMDllYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDEyNGE2MmYzOWVjNDFkNmExMmZjMWVmMGEzYWJmZjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzkwMTQ2LCAtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iNTAzNGUwMDI3ZGQ0MTg0YTFlNGMyYzM2ZDA2M2Y0NiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzI5YmViNmNmNjFkNDEyOThmNzk5ZTkwM2RlZTM2M2MgPSAkKGA8ZGl2IGlkPSJodG1sXzcyOWJlYjZjZjYxZDQxMjk4Zjc5OWU5MDNkZWUzNjNjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYjUwMzRlMDAyN2RkNDE4NGExZTRjMmMzNmQwNjNmNDYuc2V0Q29udGVudChodG1sXzcyOWJlYjZjZjYxZDQxMjk4Zjc5OWU5MDNkZWUzNjNjKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80MTI0YTYyZjM5ZWM0MWQ2YTEyZmMxZWYwYTNhYmZmNi5iaW5kUG9wdXAocG9wdXBfYjUwMzRlMDAyN2RkNDE4NGExZTRjMmMzNmQwNjNmNDYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYwYzNkMDNmOGJlMDRjZmE4MzA3NzkzNTE4MGI0MDQ2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY4OTk4NSwgLTc5LjMxNTU3MTU5OTk5OTk4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lMzE2NTc1ZGQ1NWM0NDFkYmY3ZDQ0ZGRlNzRjOGQwNCA9ICQoYDxkaXYgaWQ9Imh0bWxfZTMxNjU3NWRkNTVjNDQxZGJmN2Q0NGRkZTc0YzhkMDQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkluZGlhIEJhemFhciwgVGhlIEJlYWNoZXMgV2VzdCwgRWFzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5LnNldENvbnRlbnQoaHRtbF9lMzE2NTc1ZGQ1NWM0NDFkYmY3ZDQ0ZGRlNzRjOGQwNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjBjM2QwM2Y4YmUwNGNmYTgzMDc3OTM1MTgwYjQwNDYuYmluZFBvcHVwKHBvcHVwXzYyNzQ1NDlhODNmZTRjYzZiY2FjN2E2MDU2YTc2NTc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kMzc4MGQ4ZmMzYTk0Y2Y5YTE2Yjg1NTYwNWJjYWQ1NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODE5ODUsIC03OS4zNzk4MTY5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80OGJhY2VlOTI0ZDg0OTFlYjM5OTJiNWZjZWQ3ZTgzNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfOGE4YTQ2ODIzZjkzNDU2MmE4ZWQ5ZGY1MzFlMWI1MjkgPSAkKGA8ZGl2IGlkPSJodG1sXzhhOGE0NjgyM2Y5MzQ1NjJhOGVkOWRmNTMxZTFiNTI5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Db21tZXJjZSBDb3VydCwgVmljdG9yaWEgSG90ZWwsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDhiYWNlZTkyNGQ4NDkxZWIzOTkyYjVmY2VkN2U4MzQuc2V0Q29udGVudChodG1sXzhhOGE0NjgyM2Y5MzQ1NjJhOGVkOWRmNTMxZTFiNTI5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9kMzc4MGQ4ZmMzYTk0Y2Y5YTE2Yjg1NTYwNWJjYWQ1Ny5iaW5kUG9wdXAocG9wdXBfNDhiYWNlZTkyNGQ4NDkxZWIzOTkyYjVmY2VkN2U4MzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzZmNTU4NmFkNjZkNzQxMWJhODU0ODNhYmU1MWQ5YjVkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzEzNzU2MjAwMDAwMDA2LCAtNzkuNDkwMDczOF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81MzAxZTViMzRiZjY0NGUwYmMxN2ViM2UzYzBmZjlmMiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZmFiNjViOGM1ZDBjNGUzZjliNzNkZDFiZGYzMDY2YTggPSAkKGA8ZGl2IGlkPSJodG1sX2ZhYjY1YjhjNWQwYzRlM2Y5YjczZGQxYmRmMzA2NmE4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBQYXJrLCBNYXBsZSBMZWFmIFBhcmssIFVwd29vZCBQYXJrLCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUzMDFlNWIzNGJmNjQ0ZTBiYzE3ZWIzZTNjMGZmOWYyLnNldENvbnRlbnQoaHRtbF9mYWI2NWI4YzVkMGM0ZTNmOWI3M2RkMWJkZjMwNjZhOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNmY1NTg2YWQ2NmQ3NDExYmE4NTQ4M2FiZTUxZDliNWQuYmluZFBvcHVwKHBvcHVwXzUzMDFlNWIzNGJmNjQ0ZTBiYzE3ZWIzZTNjMGZmOWYyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82NTc3MzA4YTM3YTg0YzI5ODE1YzAwMzIxNThhMmZkZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NjMwMzMsIC03OS41NjU5NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMWRjOGI2OTRhMmM0YTdiODhmOGM2YmQxMGQ1MDc2OCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNTMwMGY1NmYyZWNiNGNkMDhmMDFkMDk3N2Y3M2IyMmEgPSAkKGA8ZGl2IGlkPSJodG1sXzUzMDBmNTZmMmVjYjRjZDA4ZjAxZDA5NzdmNzNiMjJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1iZXIgU3VtbWl0LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMxZGM4YjY5NGEyYzRhN2I4OGY4YzZiZDEwZDUwNzY4LnNldENvbnRlbnQoaHRtbF81MzAwZjU2ZjJlY2I0Y2QwOGYwMWQwOTc3ZjczYjIyYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjU3NzMwOGEzN2E4NGMyOTgxNWMwMDMyMTU4YTJmZGQuYmluZFBvcHVwKHBvcHVwXzMxZGM4YjY5NGEyYzRhN2I4OGY4YzZiZDEwZDUwNzY4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kN2I2NTU5MjZhNjY0YjMzOTVlNjNhZmFkZTJlZTFjMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNjMxNiwgLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc2ODI0YmZhZDNlNjQ1OGZiZTJmNWU1YjkyNGVlODZmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yOTc0YTFkZTZmNTg0YTA3YmRiYjUwZjQwN2FiMDE3NSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjk3NGExZGU2ZjU4NGEwN2JkYmI1MGY0MDdhYjAxNzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNsaWZmc2lkZSwgQ2xpZmZjcmVzdCwgU2NhcmJvcm91Z2ggVmlsbGFnZSBXZXN0LCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83NjgyNGJmYWQzZTY0NThmYmUyZjVlNWI5MjRlZTg2Zi5zZXRDb250ZW50KGh0bWxfMjk3NGExZGU2ZjU4NGEwN2JkYmI1MGY0MDdhYjAxNzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q3YjY1NTkyNmE2NjRiMzM5NWU2M2FmYWRlMmVlMWMwLmJpbmRQb3B1cChwb3B1cF83NjgyNGJmYWQzZTY0NThmYmUyZjVlNWI5MjRlZTg2ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjhhNmFlN2VjM2EwNDQ4OGJlM2Q0MDZjYjAxZjc4OWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODkwNTMsIC03OS40MDg0OTI3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzBkODk0ZTBiMzhjNDg0NGI5NzE3N2ZmNmZmM2FhYzUgPSAkKGA8ZGl2IGlkPSJodG1sXzcwZDg5NGUwYjM4YzQ4NDRiOTcxNzdmZjZmZjNhYWM1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlLCBOZXd0b25icm9vaywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOC5zZXRDb250ZW50KGh0bWxfNzBkODk0ZTBiMzhjNDg0NGI5NzE3N2ZmNmZmM2FhYzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI4YTZhZTdlYzNhMDQ0ODhiZTNkNDA2Y2IwMWY3ODliLmJpbmRQb3B1cChwb3B1cF83OWFkYjE0YzVlYjI0ZmE0YjJjZDc0ZTYwNmFkM2MxOCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWQ5YzE2ZmU0OGFkNDQ2NzliNzFiZWFjNTM2MDQ0ZTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjg0OTY0LCAtNzkuNDk1Njk3NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMTQ2MmQ4MmIyZTdiNDM5ZmFhYWI5NDAxMzgzM2UwMzEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2EyNTk0ZTZhY2NhMzRmOWI5YjFjYTVkYWQ2ZjNiYmQ1ID0gJChgPGRpdiBpZD0iaHRtbF9hMjU5NGU2YWNjYTM0ZjliOWIxY2E1ZGFkNmYzYmJkNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzE0NjJkODJiMmU3YjQzOWZhYWFiOTQwMTM4MzNlMDMxLnNldENvbnRlbnQoaHRtbF9hMjU5NGU2YWNjYTM0ZjliOWIxY2E1ZGFkNmYzYmJkNSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZWQ5YzE2ZmU0OGFkNDQ2NzliNzFiZWFjNTM2MDQ0ZTUuYmluZFBvcHVwKHBvcHVwXzE0NjJkODJiMmU3YjQzOWZhYWFiOTQwMTM4MzNlMDMxKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wYjZhNjg0ODFlOTU0NjEzYTJmYzliOTU0YzM2ZTRmYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1OTUyNTUsIC03OS4zNDA5MjNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNiNDg5Y2VlZGZhNzRhNTc5NTEzZDVkYWNkYjMwZDRiID0gJChgPGRpdiBpZD0iaHRtbF8zYjQ4OWNlZWRmYTc0YTU3OTUxM2Q1ZGFjZGIzMGQ0YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3R1ZGlvIERpc3RyaWN0LCBFYXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIuc2V0Q29udGVudChodG1sXzNiNDg5Y2VlZGZhNzRhNTc5NTEzZDVkYWNkYjMwZDRiKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYjZhNjg0ODFlOTU0NjEzYTJmYzliOTU0YzM2ZTRmYi5iaW5kUG9wdXAocG9wdXBfMmZmNzA1OTdmYTIzNGE2NmEwZGRmMWRlNzQ1ZDcxOTIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIwMDhjM2I5NzI5NjQ5OGU4NDA1ZmY3YWNjM2M4ZTlkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzMzMjgyNSwgLTc5LjQxOTc0OTddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWFhZmVkYmQzMDU2NGM1NTllOGM1ZWM1NWQwYWQ5YTggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzJhMDkwYjhhODkyZTRhZTlhMzJmZjJiZjIxY2M3ZTZiID0gJChgPGRpdiBpZD0iaHRtbF8yYTA5MGI4YTg5MmU0YWU5YTMyZmYyYmYyMWNjN2U2YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmVkZm9yZCBQYXJrLCBMYXdyZW5jZSBNYW5vciBFYXN0LCBOb3J0aCBZb3JrPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2VhYWZlZGJkMzA1NjRjNTU5ZThjNWVjNTVkMGFkOWE4LnNldENvbnRlbnQoaHRtbF8yYTA5MGI4YTg5MmU0YWU5YTMyZmYyYmYyMWNjN2U2Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjAwOGMzYjk3Mjk2NDk4ZTg0MDVmZjdhY2MzYzhlOWQuYmluZFBvcHVwKHBvcHVwX2VhYWZlZGJkMzA1NjRjNTU5ZThjNWVjNTVkMGFkOWE4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNmY5YjJkMmJjM2U0NmEzYWNhYmJiNjBhMjU0NTAxMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5MTExNTgsIC03OS40NzYwMTMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9mMzc2YWUyMDk5ZWU0ZTFlYjM5NzljNDE2ODlkZTcxMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWM3NjM0YmYzMDI5NGFjMThiMzY3YmQxMzJjOTE1NzMgPSAkKGA8ZGl2IGlkPSJodG1sXzFjNzYzNGJmMzAyOTRhYzE4YjM2N2JkMTMyYzkxNTczIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EZWwgUmF5LCBNb3VudCBEZW5uaXMsIEtlZWxzZGFsZSBhbmQgU2lsdmVydGhvcm4sIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZjM3NmFlMjA5OWVlNGUxZWIzOTc5YzQxNjg5ZGU3MTMuc2V0Q29udGVudChodG1sXzFjNzYzNGJmMzAyOTRhYzE4YjM2N2JkMTMyYzkxNTczKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mNmY5YjJkMmJjM2U0NmEzYWNhYmJiNjBhMjU0NTAxMS5iaW5kUG9wdXAocG9wdXBfZjM3NmFlMjA5OWVlNGUxZWIzOTc5YzQxNjg5ZGU3MTMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYxOTQ1NjcwOWZmOTRkZTRiMGM3NjcyOTE5Yzk0YjIxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI0NzY1OSwgLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2ZmZTE2NWFiZGYwMDQ4ZTlhNjY4NTE3Yjg3ZDE2NzA2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iMzg0MTEyZTgyYjM0ZDg4OGY0OGZkNGZlNWNlYjI4ZCA9ICQoYDxkaXYgaWQ9Imh0bWxfYjM4NDExMmU4MmIzNGQ4ODhmNDhmZDRmZTVjZWIyOGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWJlcmxlYSwgRW1lcnksIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZmZlMTY1YWJkZjAwNDhlOWE2Njg1MTdiODdkMTY3MDYuc2V0Q29udGVudChodG1sX2IzODQxMTJlODJiMzRkODg4ZjQ4ZmQ0ZmU1Y2ViMjhkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MTk0NTY3MDlmZjk0ZGU0YjBjNzY3MjkxOWM5NGIyMS5iaW5kUG9wdXAocG9wdXBfZmZlMTY1YWJkZjAwNDhlOWE2Njg1MTdiODdkMTY3MDYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2M3ZjNiNzI3Njg0ZTRiMDY5NTg5N2FjMGUxNGU0MDM3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkyNjU3MDAwMDAwMDA0LCAtNzkuMjY0ODQ4MV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80YWY1YTBkYjdjZmI0OWM2YjQyNGI3OGQwMDQxMDlhYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNzkzNTMzMTNmYTllNDQ1ZTlkOGE4YjAxOGVmYTM2YjQgPSAkKGA8ZGl2IGlkPSJodG1sXzc5MzUzMzEzZmE5ZTQ0NWU5ZDhhOGIwMThlZmEzNmI0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CaXJjaCBDbGlmZiwgQ2xpZmZzaWRlIFdlc3QsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzRhZjVhMGRiN2NmYjQ5YzZiNDI0Yjc4ZDAwNDEwOWFiLnNldENvbnRlbnQoaHRtbF83OTM1MzMxM2ZhOWU0NDVlOWQ4YThiMDE4ZWZhMzZiNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzdmM2I3Mjc2ODRlNGIwNjk1ODk3YWMwZTE0ZTQwMzcuYmluZFBvcHVwKHBvcHVwXzRhZjVhMGRiN2NmYjQ5YzZiNDI0Yjc4ZDAwNDEwOWFiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82MDE0YzI0YzNiNGU0N2U3OGY4ODQ0ZjFmNWIwZGUwYSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc3MDExOTksIC03OS40MDg0OTI3OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lYzRlODZjMmRmYjE0MDhkOTA5ZDRmZWQ1ODQyNGE5NSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDU4NzNjODEzOTJhNDI2MGFlY2YwNWY4NmM2YjRjZDUgPSAkKGA8ZGl2IGlkPSJodG1sXzQ1ODczYzgxMzkyYTQyNjBhZWNmMDVmODZjNmI0Y2Q1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaWxsb3dkYWxlLCBXaWxsb3dkYWxlIEVhc3QsIE5vcnRoIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWM0ZTg2YzJkZmIxNDA4ZDkwOWQ0ZmVkNTg0MjRhOTUuc2V0Q29udGVudChodG1sXzQ1ODczYzgxMzkyYTQyNjBhZWNmMDVmODZjNmI0Y2Q1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MDE0YzI0YzNiNGU0N2U3OGY4ODQ0ZjFmNWIwZGUwYS5iaW5kUG9wdXAocG9wdXBfZWM0ZTg2YzJkZmIxNDA4ZDkwOWQ0ZmVkNTg0MjRhOTUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY1MDE0YWI5N2U4OTQxYjU5ZWJiYjk3ZmMzYTM0Njc4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYxNjMxMywgLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2JjZGNkODVkNDY0ZTQxZWE4NGM0ZTJmZGJmMjNkMWRlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wMjljYWYxOGFhY2U0OThmOTQyNDUxZGZmYzE3YzBjNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMDI5Y2FmMThhYWNlNDk4Zjk0MjQ1MWRmZmMxN2MwYzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldywgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iY2RjZDg1ZDQ2NGU0MWVhODRjNGUyZmRiZjIzZDFkZS5zZXRDb250ZW50KGh0bWxfMDI5Y2FmMThhYWNlNDk4Zjk0MjQ1MWRmZmMxN2MwYzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY1MDE0YWI5N2U4OTQxYjU5ZWJiYjk3ZmMzYTM0Njc4LmJpbmRQb3B1cChwb3B1cF9iY2RjZDg1ZDQ2NGU0MWVhODRjNGUyZmRiZjIzZDFkZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmFiZDFiZTZkZmQxNDU5NTljYmVjNWFkNjI3M2E4NTcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjgwMjA1LCAtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iZjlmODQ1NmY1NzM0MzdhOGY0NGMyMmYxNmQ5OGQ4MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfY2M2MTcyZDMyNWY1NDg4MmJhNWE1MWNjOTFhZDYxMTMgPSAkKGA8ZGl2IGlkPSJodG1sX2NjNjE3MmQzMjVmNTQ4ODJiYTVhNTFjYzkxYWQ2MTEzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MYXdyZW5jZSBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYmY5Zjg0NTZmNTczNDM3YThmNDRjMjJmMTZkOThkODIuc2V0Q29udGVudChodG1sX2NjNjE3MmQzMjVmNTQ4ODJiYTVhNTFjYzkxYWQ2MTEzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yYWJkMWJlNmRmZDE0NTk1OWNiZWM1YWQ2MjczYTg1Ny5iaW5kUG9wdXAocG9wdXBfYmY5Zjg0NTZmNTczNDM3YThmNDRjMjJmMTZkOThkODIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA3MWUxNWViNzk0NjQ3NDRiMDgyMDcxNTBkODZkMjNmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzExNjk0OCwgLTc5LjQxNjkzNTU5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM0ZjFiZDAyOTRkMzQxMGRiZjZlYjY2ZTEyMjdiMTY4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lOWM5YjI1YzU5MjM0NzBkYWFmMGRkN2I1OWFkZjFhNSA9ICQoYDxkaXYgaWQ9Imh0bWxfZTljOWIyNWM1OTIzNDcwZGFhZjBkZDdiNTlhZGYxYTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VsYXduLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzRmMWJkMDI5NGQzNDEwZGJmNmViNjZlMTIyN2IxNjguc2V0Q29udGVudChodG1sX2U5YzliMjVjNTkyMzQ3MGRhYWYwZGQ3YjU5YWRmMWE1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wNzFlMTVlYjc5NDY0NzQ0YjA4MjA3MTUwZDg2ZDIzZi5iaW5kUG9wdXAocG9wdXBfMzRmMWJkMDI5NGQzNDEwZGJmNmViNjZlMTIyN2IxNjgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFiYjE2NjA3MWY0YjQ1NjFhOTEzYWJhYzA3MTNiODllID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjczMTg1Mjk5OTk5OTksIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNGQxNmVjMDc2NjBiNDllZDk5MDNhYWRiZDg3NjM4MDUgPSAkKGA8ZGl2IGlkPSJodG1sXzRkMTZlYzA3NjYwYjQ5ZWQ5OTAzYWFkYmQ4NzYzODA1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFRoZSBKdW5jdGlvbiBOb3J0aCwgWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYi5zZXRDb250ZW50KGh0bWxfNGQxNmVjMDc2NjBiNDllZDk5MDNhYWRiZDg3NjM4MDUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzFiYjE2NjA3MWY0YjQ1NjFhOTEzYWJhYzA3MTNiODllLmJpbmRQb3B1cChwb3B1cF9hY2M3ZGM1ZWVhZDM0MjFlYmM2MmRmYTg0YjlkMTcyYikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMmEyNGY3MWZlODkyNDJhODlhM2Q3YjZlMTc2OTAzMjMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsIC03OS41MTgxODg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lZmJkMjJmZDhjYjQ0NTQzYWIyMjY0MjI4ZjUxMjUzNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZTk5Y2VkNTI2NjRhNGU5Mjg1M2U5YTg1MjU3NTdlNmEgPSAkKGA8ZGl2IGlkPSJodG1sX2U5OWNlZDUyNjY0YTRlOTI4NTNlOWE4NTI1NzU3ZTZhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0b24sIFlvcms8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWZiZDIyZmQ4Y2I0NDU0M2FiMjI2NDIyOGY1MTI1MzQuc2V0Q29udGVudChodG1sX2U5OWNlZDUyNjY0YTRlOTI4NTNlOWE4NTI1NzU3ZTZhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yYTI0ZjcxZmU4OTI0MmE4OWEzZDdiNmUxNzY5MDMyMy5iaW5kUG9wdXAocG9wdXBfZWZiZDIyZmQ4Y2I0NDU0M2FiMjI2NDIyOGY1MTI1MzQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzg4NzVjMzAwZDc1ZDQ1NThhZjA0ZGZiZDQ1YmFmODJjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDA5NiwgLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhjMDhmOTU3YTY4MDQxMjQ4ZGIzZTIwY2Y1NTVmMjQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80NTE1ZTg2MGI2OWI0NjM1OGJmNzRkMTgxNDM1MGZkZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNDUxNWU4NjBiNjliNDYzNThiZjc0ZDE4MTQzNTBmZGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrLCBXZXhmb3JkIEhlaWdodHMsIFNjYXJib3JvdWdoIFRvd24gQ2VudHJlLCBTY2FyYm9yb3VnaDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF84YzA4Zjk1N2E2ODA0MTI0OGRiM2UyMGNmNTU1ZjI0NC5zZXRDb250ZW50KGh0bWxfNDUxNWU4NjBiNjliNDYzNThiZjc0ZDE4MTQzNTBmZGQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzg4NzVjMzAwZDc1ZDQ1NThhZjA0ZGZiZDQ1YmFmODJjLmJpbmRQb3B1cChwb3B1cF84YzA4Zjk1N2E2ODA0MTI0OGRiM2UyMGNmNTU1ZjI0NCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzBmOTIzMDY0ZGYyNDNhM2IyYzUzYjM2YTkzYjIxZjUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTI3NTgyOTk5OTk5OTYsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcwNWZkNTY2OWY1NDRhODZiMzUyNmQ1ODVlMWI1MGU0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81ZTY4ZjFiMWUyN2Y0YTIzOTNlOGQwYzliN2VkZjgxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWU2OGYxYjFlMjdmNGEyMzkzZThkMGM5YjdlZGY4MTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPllvcmsgTWlsbHMgV2VzdCwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MDVmZDU2NjlmNTQ0YTg2YjM1MjZkNTg1ZTFiNTBlNC5zZXRDb250ZW50KGh0bWxfNWU2OGYxYjFlMjdmNGEyMzkzZThkMGM5YjdlZGY4MTgpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2MwZjkyMzA2NGRmMjQzYTNiMmM1M2IzNmE5M2IyMWY1LmJpbmRQb3B1cChwb3B1cF83MDVmZDU2NjlmNTQ0YTg2YjM1MjZkNTg1ZTFiNTBlNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDU5ZDRiYTc5YmQwNGMzYmE4ZmU2ZTExZmZhZGUwYzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTI3NTExLCAtNzkuMzkwMTk3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9hNDlhNDc0NzAyNzg0MGRhYThiYWRjYjQ2ZjE3NjBlYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWY3NmNkYTk1NTUyNDRlM2JiYzNhYmQ0OGJiZjIzOWEgPSAkKGA8ZGl2IGlkPSJodG1sXzFmNzZjZGE5NTU1MjQ0ZTNiYmMzYWJkNDhiYmYyMzlhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIE5vcnRoLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTQ5YTQ3NDcwMjc4NDBkYWE4YmFkY2I0NmYxNzYwZWMuc2V0Q29udGVudChodG1sXzFmNzZjZGE5NTU1MjQ0ZTNiYmMzYWJkNDhiYmYyMzlhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wNTlkNGJhNzliZDA0YzNiYThmZTZlMTFmZmFkZTBjMS5iaW5kUG9wdXAocG9wdXBfYTQ5YTQ3NDcwMjc4NDBkYWE4YmFkY2I0NmYxNzYwZWMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA5ODJlMzYzNjg2YjRiZDdiZWRlNzgyYzgwYzk2NDA0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2OTQ3NiwgLTc5LjQxMTMwNzIwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83YmI4NzYwMDA1M2U0YmJiODNlNGI4YWRmNDY5YTk0MyA9ICQoYDxkaXYgaWQ9Imh0bWxfN2JiODc2MDAwNTNlNGJiYjgzZTRiOGFkZjQ2OWE5NDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZvcmVzdCBIaWxsIE5vcnRoICZhbXA7IFdlc3QsIEZvcmVzdCBIaWxsIFJvYWQgUGFyaywgQ2VudHJhbCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2LnNldENvbnRlbnQoaHRtbF83YmI4NzYwMDA1M2U0YmJiODNlNGI4YWRmNDY5YTk0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDk4MmUzNjM2ODZiNGJkN2JlZGU3ODJjODBjOTY0MDQuYmluZFBvcHVwKHBvcHVwX2U2ZDE4ODIxYTY0MzRmMTM4NDJjODNlZTZkZTUzYzA2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jOWRiOTViMTExYTk0MjcxODQ4MjBiNDI3MTk5ZjUzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MTYwODMsIC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jZTBlMTJmMDc3NWE0MWRlOWRlZjk4ODRiNDY3NGY2MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzg0MGNiODJkYmYzNGE3ZWE0NTU3MjU1OTM5NmE4NjMgPSAkKGA8ZGl2IGlkPSJodG1sXzM4NDBjYjgyZGJmMzRhN2VhNDU1NzI1NTkzOTZhODYzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IaWdoIFBhcmssIFRoZSBKdW5jdGlvbiBTb3V0aCwgV2VzdCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2NlMGUxMmYwNzc1YTQxZGU5ZGVmOTg4NGI0Njc0ZjYyLnNldENvbnRlbnQoaHRtbF8zODQwY2I4MmRiZjM0YTdlYTQ1NTcyNTU5Mzk2YTg2Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzlkYjk1YjExMWE5NDI3MTg0ODIwYjQyNzE5OWY1MzguYmluZFBvcHVwKHBvcHVwX2NlMGUxMmYwNzc1YTQxZGU5ZGVmOTg4NGI0Njc0ZjYyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MGRjNDgwYzlhY2E0OWJjYTI0ZDcyMGRlZGFkMGY3NyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5NjMxOSwgLTc5LjUzMjI0MjQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8yODZhZDA3MGJkYzI0ZWUzYjM3ZTJhZDFhMTZhMjM5MyA9ICQoYDxkaXYgaWQ9Imh0bWxfMjg2YWQwNzBiZGMyNGVlM2IzN2UyYWQxYTE2YTIzOTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldlc3Rtb3VudCwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwLnNldENvbnRlbnQoaHRtbF8yODZhZDA3MGJkYzI0ZWUzYjM3ZTJhZDFhMTZhMjM5Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNTBkYzQ4MGM5YWNhNDliY2EyNGQ3MjBkZWRhZDBmNzcuYmluZFBvcHVwKHBvcHVwXzM1ODhiNzhkNzNiNjQzYzI5ZGM3MmI4MzMxMGQxZTAwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hOTZmM2M1ZGQ0NmQ0ZGM2OTI3YWQyN2IwNmVkZWRkOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwgLTc5LjI5NTg0OTFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmUzNGFmYTUwYzE3NGIyMzk4MjYzMjI1M2U2YjE5NWMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzcwMDk1NDEzYjA3ZjRiZjI4MzAyZmRiYTNkMTFmNTJmID0gJChgPGRpdiBpZD0iaHRtbF83MDA5NTQxM2IwN2Y0YmYyODMwMmZkYmEzZDExZjUyZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2V4Zm9yZCwgTWFyeXZhbGUsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzJlMzRhZmE1MGMxNzRiMjM5ODI2MzIyNTNlNmIxOTVjLnNldENvbnRlbnQoaHRtbF83MDA5NTQxM2IwN2Y0YmYyODMwMmZkYmEzZDExZjUyZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTk2ZjNjNWRkNDZkNGRjNjkyN2FkMjdiMDZlZGVkZDguYmluZFBvcHVwKHBvcHVwXzJlMzRhZmE1MGMxNzRiMjM5ODI2MzIyNTNlNmIxOTVjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mOTc5NGZkYWI1YmQ0NDJmYTJiZWMzNWFmOWUwMzRiOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4MjczNjQsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IyZjhiY2ViNWJhNDQxMWQ4NDkyOWIzMjIwOWEwMDdlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zZjE2ODkwYTNkNjM0NzU5OGM3NTE0N2E0ODY5OTI3MiA9ICQoYDxkaXYgaWQ9Imh0bWxfM2YxNjg5MGEzZDYzNDc1OThjNzUxNDdhNDg2OTkyNzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldpbGxvd2RhbGUsIFdpbGxvd2RhbGUgV2VzdCwgTm9ydGggWW9yazwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iMmY4YmNlYjViYTQ0MTFkODQ5MjliMzIyMDlhMDA3ZS5zZXRDb250ZW50KGh0bWxfM2YxNjg5MGEzZDYzNDc1OThjNzUxNDdhNDg2OTkyNzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Y5Nzk0ZmRhYjViZDQ0MmZhMmJlYzM1YWY5ZTAzNGI4LmJpbmRQb3B1cChwb3B1cF9iMmY4YmNlYjViYTQ0MTFkODQ5MjliMzIyMDlhMDA3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWMyNmViZjQ1YzQ4NDM4Y2E2NjZhNzAyM2QzODQ3N2EgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTUzODM0LCAtNzkuNDA1Njc4NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVjNTQwYzc0YTA3MzRiNTNhNzNkNjVlZmYyM2E2YjcyID0gJChgPGRpdiBpZD0iaHRtbF81YzU0MGM3NGEwNzM0YjUzYTczZDY1ZWZmMjNhNmI3MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGggVG9yb250byBXZXN0LCBMYXdyZW5jZSBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUuc2V0Q29udGVudChodG1sXzVjNTQwYzc0YTA3MzRiNTNhNzNkNjVlZmYyM2E2YjcyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hYzI2ZWJmNDVjNDg0MzhjYTY2NmE3MDIzZDM4NDc3YS5iaW5kUG9wdXAocG9wdXBfOGYzNmU3ODkwOTYxNDk2NTgxM2JkMzVhMmU2OTI3NWUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjMjk0YWVhNDIwMjRkYjJiMzhkYmYwYzliOWViNjE2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywgLTc5LjQwNTY3ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzE4NTU4N2Q1MzNkZjQwMDg4Y2E5NjZiNzM2MDkzMDI2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jOTdhNDQ2YjY1NjI0Y2MzOTEzMDI0NTQyMzI2ZjEzZSA9ICQoYDxkaXYgaWQ9Imh0bWxfYzk3YTQ0NmI2NTYyNGNjMzkxMzAyNDU0MjMyNmYxM2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBBbm5leCwgTm9ydGggTWlkdG93biwgWW9ya3ZpbGxlLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMTg1NTg3ZDUzM2RmNDAwODhjYTk2NmI3MzYwOTMwMjYuc2V0Q29udGVudChodG1sX2M5N2E0NDZiNjU2MjRjYzM5MTMwMjQ1NDIzMjZmMTNlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jYzI5NGFlYTQyMDI0ZGIyYjM4ZGJmMGM5YjllYjYxNi5iaW5kUG9wdXAocG9wdXBfMTg1NTg3ZDUzM2RmNDAwODhjYTk2NmI3MzYwOTMwMjYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdmNGNiMjVjMjEyZjRjNzNiZmEwMWZlOTUxNDg5NGQ5ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4OTU5NywgLTc5LjQ1NjMyNV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wYjMyZWNlOWUzNDA0NWE3YjNjOTgzODBmNWI3YzYyYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzkyYTI3NDg3Y2ZjNDgxNDkxN2NkZGY4Mjk4ZTA0M2QgPSAkKGA8ZGl2IGlkPSJodG1sX2M5MmEyNzQ4N2NmYzQ4MTQ5MTdjZGRmODI5OGUwNDNkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrZGFsZSwgUm9uY2VzdmFsbGVzLCBXZXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGIzMmVjZTllMzQwNDVhN2IzYzk4MzgwZjViN2M2MmEuc2V0Q29udGVudChodG1sX2M5MmEyNzQ4N2NmYzQ4MTQ5MTdjZGRmODI5OGUwNDNkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83ZjRjYjI1YzIxMmY0YzczYmZhMDFmZTk1MTQ4OTRkOS5iaW5kUG9wdXAocG9wdXBfMGIzMmVjZTllMzQwNDVhN2IzYzk4MzgwZjViN2M2MmEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdlYmE2MmMzZWFkOTQ1YzhhZTBkMDVkMTYyZTA2MWQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2OTY1NiwgLTc5LjYxNTgxODk5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wNTFlZWYyYTg4YjA0NDVhOWJmMzlkM2MwNWVjN2U4YyA9ICQoYDxkaXYgaWQ9Imh0bWxfMDUxZWVmMmE4OGIwNDQ1YTliZjM5ZDNjMDVlYzdlOGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNhbmFkYSBQb3N0IEdhdGV3YXkgUHJvY2Vzc2luZyBDZW50cmUsIE1pc3Npc3NhdWdhPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlLnNldENvbnRlbnQoaHRtbF8wNTFlZWYyYTg4YjA0NDVhOWJmMzlkM2MwNWVjN2U4Yyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfN2ViYTYyYzNlYWQ5NDVjOGFlMGQwNWQxNjJlMDYxZDAuYmluZFBvcHVwKHBvcHVwX2RiZWEyYmE2YTQxMjRhZGQ5ODQ1ODExN2NiMTM0NzVlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lY2M5MDY4MTZhNmI0MDFkODA2Zjc4ZmE2MTk0NWM3NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4ODkwNTQsIC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85OTI4ODdlNWY1MzA0MzE0YWEwZTBjZjNiNDdkOGE4YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjdlMmY3MzA1NGEzNGNiMGI0YzRmMzZiOWQyNDQ5YWEgPSAkKGA8ZGl2IGlkPSJodG1sX2Y3ZTJmNzMwNTRhMzRjYjBiNGM0ZjM2YjlkMjQ0OWFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5LaW5nc3ZpZXcgVmlsbGFnZSwgU3QuIFBoaWxsaXBzLCBNYXJ0aW4gR3JvdmUgR2FyZGVucywgUmljaHZpZXcgR2FyZGVucywgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk5Mjg4N2U1ZjUzMDQzMTRhYTBlMGNmM2I0N2Q4YThiLnNldENvbnRlbnQoaHRtbF9mN2UyZjczMDU0YTM0Y2IwYjRjNGYzNmI5ZDI0NDlhYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZWNjOTA2ODE2YTZiNDAxZDgwNmY3OGZhNjE5NDVjNzQuYmluZFBvcHVwKHBvcHVwXzk5Mjg4N2U1ZjUzMDQzMTRhYTBlMGNmM2I0N2Q4YThiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kOTk3YTE4MDhmZWU0MTBkOGIyNzQ2YTIzYmUyYzlkYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5NDIwMDMsIC03OS4yNjIwMjk0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yN2E0OGY5NTFiNTM0MTYwODlkNjc5MDhhNTVlM2UxMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDZlNzJjNTcxNmM5NGUyOGEwMDM4ZThhYTEwZmJhZDQgPSAkKGA8ZGl2IGlkPSJodG1sXzQ2ZTcyYzU3MTZjOTRlMjhhMDAzOGU4YWExMGZiYWQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BZ2luY291cnQsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzI3YTQ4Zjk1MWI1MzQxNjA4OWQ2NzkwOGE1NWUzZTEzLnNldENvbnRlbnQoaHRtbF80NmU3MmM1NzE2Yzk0ZTI4YTAwMzhlOGFhMTBmYmFkNCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDk5N2ExODA4ZmVlNDEwZDhiMjc0NmEyM2JlMmM5ZGIuYmluZFBvcHVwKHBvcHVwXzI3YTQ4Zjk1MWI1MzQxNjA4OWQ2NzkwOGE1NWUzZTEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMGYxODY5ZGRmNDQ0N2NhYTQwNmUwNjBjZDk5NmE3OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNDMyNDQsIC03OS4zODg3OTAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2I0YjAwMTg4Y2QwMTQzMjFiZjY1ODc4M2VhOTNkMGJkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kZDAwNWVjNGI1ZmU0OGZmOGE5ZjkyNjI1OGNmZjEzNCA9ICQoYDxkaXYgaWQ9Imh0bWxfZGQwMDVlYzRiNWZlNDhmZjhhOWY5MjYyNThjZmYxMzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRhdmlzdmlsbGUsIENlbnRyYWwgVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iNGIwMDE4OGNkMDE0MzIxYmY2NTg3ODNlYTkzZDBiZC5zZXRDb250ZW50KGh0bWxfZGQwMDVlYzRiNWZlNDhmZjhhOWY5MjYyNThjZmYxMzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2IwZjE4NjlkZGY0NDQ3Y2FhNDA2ZTA2MGNkOTk2YTc4LmJpbmRQb3B1cChwb3B1cF9iNGIwMDE4OGNkMDE0MzIxYmY2NTg3ODNlYTkzZDBiZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTUyN2UwMThmOGI1NDYyNTlmOTc3YWIyM2M3ODlhMmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjI2OTU2LCAtNzkuNDAwMDQ5M10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83M2QxMzdkMzZkODQ0ZjIyYjUwMjI5OWE2NWI2MzNkYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDcyMzA2YzNjN2JiNDdmYTg3M2Y2YzIwNTUxYWM2NjUgPSAkKGA8ZGl2IGlkPSJodG1sXzQ3MjMwNmMzYzdiYjQ3ZmE4NzNmNmMyMDU1MWFjNjY1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Vbml2ZXJzaXR5IG9mIFRvcm9udG8sIEhhcmJvcmQsIERvd250b3duIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzNkMTM3ZDM2ZDg0NGYyMmI1MDIyOTlhNjViNjMzZGEuc2V0Q29udGVudChodG1sXzQ3MjMwNmMzYzdiYjQ3ZmE4NzNmNmMyMDU1MWFjNjY1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNTI3ZTAxOGY4YjU0NjI1OWY5NzdhYjIzYzc4OWEyYi5iaW5kUG9wdXAocG9wdXBfNzNkMTM3ZDM2ZDg0NGYyMmI1MDIyOTlhNjViNjMzZGEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2E2NDM1OTEyNzgzODQwNDQ4YTdhODU0MTZhODdhYjlmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUxNTcwNiwgLTc5LjQ4NDQ0OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2U5ODgzNGI2ZGU0YzQ5MDhiNzE5MDhlMDk1M2NkN2M5ID0gJChgPGRpdiBpZD0iaHRtbF9lOTg4MzRiNmRlNGM0OTA4YjcxOTA4ZTA5NTNjZDdjOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UnVubnltZWRlLCBTd2Fuc2VhLCBXZXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYuc2V0Q29udGVudChodG1sX2U5ODgzNGI2ZGU0YzQ5MDhiNzE5MDhlMDk1M2NkN2M5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hNjQzNTkxMjc4Mzg0MDQ0OGE3YTg1NDE2YTg3YWI5Zi5iaW5kUG9wdXAocG9wdXBfMDU4OTRjYmE3OTdmNDdlZTg5ZmRlZGE0ZTIzN2I3MzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzVlYmU3ZjM5ZDViNDRjODZiZGJjYmUxNjI2MmQ4YjVmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwgLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU1ZTJjZTBmYWU2MjQ5ZDI4MzY5MTU1ZDk0ZThiNTFhID0gJChgPGRpdiBpZD0iaHRtbF81NWUyY2UwZmFlNjI0OWQyODM2OTE1NWQ5NGU4YjUxYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xhcmtzIENvcm5lcnMsIFRhbSBPJiMzOTtTaGFudGVyLCBTdWxsaXZhbiwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcuc2V0Q29udGVudChodG1sXzU1ZTJjZTBmYWU2MjQ5ZDI4MzY5MTU1ZDk0ZThiNTFhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81ZWJlN2YzOWQ1YjQ0Yzg2YmRiY2JlMTYyNjJkOGI1Zi5iaW5kUG9wdXAocG9wdXBfNTliMjNhNTZhMzhhNGU0MDhmMzUxODljZGFlYjcyNTcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEzM2VjMjUxYmU2YzQ1OTY4ODMzZTg5NjZhZDYyYWU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg5NTc0MywgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mNjI3ZDZlMTA4NTY0ZmNmYmIwOGE3YzFmZTQ4MzJlZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZjYyN2Q2ZTEwODU2NGZjZmJiMDhhN2MxZmU0ODMyZWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1vb3JlIFBhcmssIFN1bW1lcmhpbGwgRWFzdCwgQ2VudHJhbCBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5LnNldENvbnRlbnQoaHRtbF9mNjI3ZDZlMTA4NTY0ZmNmYmIwOGE3YzFmZTQ4MzJlZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMTMzZWMyNTFiZTZjNDU5Njg4MzNlODk2NmFkNjJhZTUuYmluZFBvcHVwKHBvcHVwXzY2ZjU2NDExZjE2YjQxZTM4NWJmM2Q1OTZiYzE3MDY5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85MGFhOTM1NjE3NDM0OTQxODBiODFjMjYwM2NiZjBjNCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzIwNTcsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jY2RiZGQ0NTFlZDc0YjdkODQ4OWNmNmU1ZDFjYzMyMyA9ICQoYDxkaXYgaWQ9Imh0bWxfY2NkYmRkNDUxZWQ3NGI3ZDg0ODljZjZlNWQxY2MzMjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktlbnNpbmd0b24gTWFya2V0LCBDaGluYXRvd24sIEdyYW5nZSBQYXJrLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0LnNldENvbnRlbnQoaHRtbF9jY2RiZGQ0NTFlZDc0YjdkODQ4OWNmNmU1ZDFjYzMyMyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTBhYTkzNTYxNzQzNDk0MTgwYjgxYzI2MDNjYmYwYzQuYmluZFBvcHVwKHBvcHVwXzIxZDE2ZjlhZDJiNTRiN2M5OGE0ODA2MWUzYjcyNWQ0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wYWU3N2FjZWNhMGQ0M2UwYmEyMzJmNDg5ZDA4NGQyOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzZiMTcxMjQ3NzVmNjQzZDE5NzYxYWRhM2QwN2M0ZTRhID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80ZWVhZWZiZWM1NjY0MDQ4OGRjZWFiZDcyYTBiZGNlOSA9ICQoYDxkaXYgaWQ9Imh0bWxfNGVlYWVmYmVjNTY2NDA0ODhkY2VhYmQ3MmEwYmRjZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbGxpa2VuLCBBZ2luY291cnQgTm9ydGgsIFN0ZWVsZXMgRWFzdCwgTCYjMzk7QW1vcmVhdXggRWFzdCwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNmIxNzEyNDc3NWY2NDNkMTk3NjFhZGEzZDA3YzRlNGEuc2V0Q29udGVudChodG1sXzRlZWFlZmJlYzU2NjQwNDg4ZGNlYWJkNzJhMGJkY2U5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYWU3N2FjZWNhMGQ0M2UwYmEyMzJmNDg5ZDA4NGQyOC5iaW5kUG9wdXAocG9wdXBfNmIxNzEyNDc3NWY2NDNkMTk3NjFhZGEzZDA3YzRlNGEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE5YWY5Yzc1YTc0OTRlYWE4NDQ3ZDI4OWRhY2Q0Mjc0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjg2NDEyMjk5OTk5OTksIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzQ1MWVjNDYxNjJmZjQxMzU4MTNjYjM1MjAwMGM4NzBjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zZTBjZTMyMmU5YzI0NzNhYThjYTNkZTNjMmRmZWNkZiA9ICQoYDxkaXYgaWQ9Imh0bWxfM2UwY2UzMjJlOWMyNDczYWE4Y2EzZGUzYzJkZmVjZGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN1bW1lcmhpbGwgV2VzdCwgUmF0aG5lbGx5LCBTb3V0aCBIaWxsLCBGb3Jlc3QgSGlsbCBTRSwgRGVlciBQYXJrLCBDZW50cmFsIFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDUxZWM0NjE2MmZmNDEzNTgxM2NiMzUyMDAwYzg3MGMuc2V0Q29udGVudChodG1sXzNlMGNlMzIyZTljMjQ3M2FhOGNhM2RlM2MyZGZlY2RmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xOWFmOWM3NWE3NDk0ZWFhODQ0N2QyODlkYWNkNDI3NC5iaW5kUG9wdXAocG9wdXBfNDUxZWM0NjE2MmZmNDEzNTgxM2NiMzUyMDAwYzg3MGMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY0YWY4MTI2ZmM2MjQ2M2Y5YTdmZTE0NGY3N2M2MTQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4OTQ2NywgLTc5LjM5NDQxOTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWIxOTA0ZGE3YjQ0NDlmNTg5MTAwOGM0Y2U0NjczZDIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzBkMmIzNzM3OTZlMzQxYzI4M2ZkM2VhYjllYjgxMjFhID0gJChgPGRpdiBpZD0iaHRtbF8wZDJiMzczNzk2ZTM0MWMyODNmZDNlYWI5ZWI4MTIxYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q04gVG93ZXIsIEtpbmcgYW5kIFNwYWRpbmEsIFJhaWx3YXkgTGFuZHMsIEhhcmJvdXJmcm9udCBXZXN0LCBCYXRodXJzdCBRdWF5LCBTb3V0aCBOaWFnYXJhLCBJc2xhbmQgYWlycG9ydCwgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hYjE5MDRkYTdiNDQ0OWY1ODkxMDA4YzRjZTQ2NzNkMi5zZXRDb250ZW50KGh0bWxfMGQyYjM3Mzc5NmUzNDFjMjgzZmQzZWFiOWViODEyMWEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY0YWY4MTI2ZmM2MjQ2M2Y5YTdmZTE0NGY3N2M2MTQwLmJpbmRQb3B1cChwb3B1cF9hYjE5MDRkYTdiNDQ0OWY1ODkxMDA4YzRjZTQ2NzNkMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZGUzYmEzOWZhYmRkNDI0NDlhNGFkYTFlMmI1NWRhZjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDU2NDY2LCAtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzI3NmI0YjMxMzY5NGM5ZTgyNWE4MDE4OTY1MDE0YjMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2IzOWZjN2RkNDgxNzQyMmU5YTM5YjYyODgyZDYxMzNlID0gJChgPGRpdiBpZD0iaHRtbF9iMzlmYzdkZDQ4MTc0MjJlOWEzOWI2Mjg4MmQ2MTMzZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TmV3IFRvcm9udG8sIE1pbWljbyBTb3V0aCwgSHVtYmVyIEJheSBTaG9yZXMsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83Mjc2YjRiMzEzNjk0YzllODI1YTgwMTg5NjUwMTRiMy5zZXRDb250ZW50KGh0bWxfYjM5ZmM3ZGQ0ODE3NDIyZTlhMzliNjI4ODJkNjEzM2UpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RlM2JhMzlmYWJkZDQyNDQ5YTRhZGExZTJiNTVkYWYxLmJpbmRQb3B1cChwb3B1cF83Mjc2YjRiMzEzNjk0YzllODI1YTgwMTg5NjUwMTRiMykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWEwZTMzNzM5YTcwNDljNjkxMjZjMDg1NTRmMGM0MGIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzk0MTYzOTk5OTk5OTYsIC03OS41ODg0MzY5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzRkNGVhMzYyNmRmNDQ1OWZhOWZkNGI0M2RlNDIzNzVkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80ZWVmN2I0ZDU2YzU0Y2IxYWRiZGJjZDMwYmZkMTczMiA9ICQoYDxkaXYgaWQ9Imh0bWxfNGVlZjdiNGQ1NmM1NGNiMWFkYmRiY2QzMGJmZDE3MzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlNvdXRoIFN0ZWVsZXMsIFNpbHZlcnN0b25lLCBIdW1iZXJnYXRlLCBKYW1lc3Rvd24sIE1vdW50IE9saXZlLCBCZWF1bW9uZCBIZWlnaHRzLCBUaGlzdGxldG93biwgQWxiaW9uIEdhcmRlbnMsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF80ZDRlYTM2MjZkZjQ0NTlmYTlmZDRiNDNkZTQyMzc1ZC5zZXRDb250ZW50KGh0bWxfNGVlZjdiNGQ1NmM1NGNiMWFkYmRiY2QzMGJmZDE3MzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2FhMGUzMzczOWE3MDQ5YzY5MTI2YzA4NTU0ZjBjNDBiLmJpbmRQb3B1cChwb3B1cF80ZDRlYTM2MjZkZjQ0NTlmYTlmZDRiNDNkZTQyMzc1ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMWE2OTBlMWIzYzQ2NGQ4M2E5NGNmNzA4YTZlN2RhMmIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43OTk1MjUyMDAwMDAwMDUsIC03OS4zMTgzODg3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2EwZmJhNWM1YTQ0NjQ1NWE5OWMyNGU2MDI1MzRhNGNmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ODdkODRlOTgxODA0Y2I0YTBlM2E0YWY2NmZmM2MxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzg3ZDg0ZTk4MTgwNGNiNGEwZTNhNGFmNjZmZjNjMTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0ZWVsZXMgV2VzdCwgTCYjMzk7QW1vcmVhdXggV2VzdCwgU2NhcmJvcm91Z2g8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYTBmYmE1YzVhNDQ2NDU1YTk5YzI0ZTYwMjUzNGE0Y2Yuc2V0Q29udGVudChodG1sXzc4N2Q4NGU5ODE4MDRjYjRhMGUzYTRhZjY2ZmYzYzE4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xYTY5MGUxYjNjNDY0ZDgzYTk0Y2Y3MDhhNmU3ZGEyYi5iaW5kUG9wdXAocG9wdXBfYTBmYmE1YzVhNDQ2NDU1YTk5YzI0ZTYwMjUzNGE0Y2YpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhlMTFiNWNmN2M1YjRmMjM4MGNiMTRkNzkxZjdiMjg3ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc5NTYyNiwgLTc5LjM3NzUyOTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZDc0NzBmODUwMTU0NjU4OTc5ZGIzYmI0MjIzY2IzYSA9ICQoYDxkaXYgaWQ9Imh0bWxfN2Q3NDcwZjg1MDE1NDY1ODk3OWRiM2JiNDIyM2NiM2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlJvc2VkYWxlLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4LnNldENvbnRlbnQoaHRtbF83ZDc0NzBmODUwMTU0NjU4OTc5ZGIzYmI0MjIzY2IzYSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGUxMWI1Y2Y3YzViNGYyMzgwY2IxNGQ3OTFmN2IyODcuYmluZFBvcHVwKHBvcHVwXzFkZGRiNmQ5Y2I5ODQ2OTE4NzZmODgwY2EwODg3MjU4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81OTc5YjBjY2UxMjk0MWJmYTNmOTg0NWQzMTdkOWQxMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NjQzNTIsIC03OS4zNzQ4NDU5OTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5YyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMmZiYzczMjkxYjMxNDk5OTgzNTVmZTVkZGIzMTc2ZTMgPSAkKGA8ZGl2IGlkPSJodG1sXzJmYmM3MzI5MWIzMTQ5OTk4MzU1ZmU1ZGRiMzE3NmUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdG4gQSBQTyBCb3hlcywgRG93bnRvd24gVG9yb250bzwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5Yy5zZXRDb250ZW50KGh0bWxfMmZiYzczMjkxYjMxNDk5OTgzNTVmZTVkZGIzMTc2ZTMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzU5NzliMGNjZTEyOTQxYmZhM2Y5ODQ1ZDMxN2Q5ZDExLmJpbmRQb3B1cChwb3B1cF9iYzQ1MTViN2U0MmM0MmYwODIwOTUzMWU1YjBiZTQ5YykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWZkNGE2NDM0NTlmNGUxNGIyYTY0ZDU1MmM4ZTM3ZDcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDI0MTM3MDAwMDAwMSwgLTc5LjU0MzQ4NDA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc4NzI2MjI4MjZjYTQ0MjJiYjFjNTViMGE5NmExZjdkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82ZjA4ODlmYmZmZjc0YmY1YmY1MmNkOGJkOTMwMWY5OSA9ICQoYDxkaXYgaWQ9Imh0bWxfNmYwODg5ZmJmZmY3NGJmNWJmNTJjZDhiZDkzMDFmOTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFsZGVyd29vZCwgTG9uZyBCcmFuY2gsIEV0b2JpY29rZTwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ODcyNjIyODI2Y2E0NDIyYmIxYzU1YjBhOTZhMWY3ZC5zZXRDb250ZW50KGh0bWxfNmYwODg5ZmJmZmY3NGJmNWJmNTJjZDhiZDkzMDFmOTkpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzlmZDRhNjQzNDU5ZjRlMTRiMmE2NGQ1NTJjOGUzN2Q3LmJpbmRQb3B1cChwb3B1cF83ODcyNjIyODI2Y2E0NDIyYmIxYzU1YjBhOTZhMWY3ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTc1YTUwZTEyYWRmNDQ4YmExNGEyYjQ2MWRhMzMwMTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY3NDgyOTk5OTk5OTQsIC03OS41OTQwNTQ0XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2ZkYjg3YmI3NmU1NjRmOWQ4ZWZhYjczZjEyZjgwZTcxID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lMzU4ZTFkYzc3NDc0N2I5OWU2Mzg5ZDQ2OGY3YzA5YiA9ICQoYDxkaXYgaWQ9Imh0bWxfZTM1OGUxZGM3NzQ3NDdiOTllNjM4OWQ0NjhmN2MwOWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRod2VzdCwgV2VzdCBIdW1iZXIgLSBDbGFpcnZpbGxlLCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZmRiODdiYjc2ZTU2NGY5ZDhlZmFiNzNmMTJmODBlNzEuc2V0Q29udGVudChodG1sX2UzNThlMWRjNzc0NzQ3Yjk5ZTYzODlkNDY4ZjdjMDliKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNzVhNTBlMTJhZGY0NDhiYTE0YTJiNDYxZGEzMzAxNS5iaW5kUG9wdXAocG9wdXBfZmRiODdiYjc2ZTU2NGY5ZDhlZmFiNzNmMTJmODBlNzEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzQ4ZWQxMWRjODNjOTRkY2VhMGQyMGJiMzI4MWZhMjNlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuODM2MTI0NzAwMDAwMDA2LCAtNzkuMjA1NjM2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTQ2MmUyZGUwYWU2NDBmYThhMzY3YzI2OGMwMWM2ZGIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2NkNTRiNDhmNDE4MzRjYjQ4ZTBmNmRlZTgzYzg3OTdiID0gJChgPGRpdiBpZD0iaHRtbF9jZDU0YjQ4ZjQxODM0Y2I0OGUwZjZkZWU4M2M4Nzk3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VXBwZXIgUm91Z2UsIFNjYXJib3JvdWdoPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzU0NjJlMmRlMGFlNjQwZmE4YTM2N2MyNjhjMDFjNmRiLnNldENvbnRlbnQoaHRtbF9jZDU0YjQ4ZjQxODM0Y2I0OGUwZjZkZWU4M2M4Nzk3Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDhlZDExZGM4M2M5NGRjZWEwZDIwYmIzMjgxZmEyM2UuYmluZFBvcHVwKHBvcHVwXzU0NjJlMmRlMGFlNjQwZmE4YTM2N2MyNjhjMDFjNmRiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZjE4MDgwMTJiYTA0ZGNiOGQyOGE3NTdhNmUyOWQxNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Nzk2NywgLTc5LjM2NzY3NTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOThmZjkzMDMzNDNhNDkzNTg3YzRhYzA3ZGY3ODBlYTUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2Y2YzNmOWFiNmFkZDQ5NmM5MDk0NDllODUxYTUxZWJmID0gJChgPGRpdiBpZD0iaHRtbF9mNmMzZjlhYjZhZGQ0OTZjOTA5NDQ5ZTg1MWE1MWViZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3QuIEphbWVzIFRvd24sIENhYmJhZ2V0b3duLCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzk4ZmY5MzAzMzQzYTQ5MzU4N2M0YWMwN2RmNzgwZWE1LnNldENvbnRlbnQoaHRtbF9mNmMzZjlhYjZhZGQ0OTZjOTA5NDQ5ZTg1MWE1MWViZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGYxODA4MDEyYmEwNGRjYjhkMjhhNzU3YTZlMjlkMTcuYmluZFBvcHVwKHBvcHVwXzk4ZmY5MzAzMzQzYTQ5MzU4N2M0YWMwN2RmNzgwZWE1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85NTExYjlhN2I3Mzc0OGJhODg0NDQ0YWM3Mzc4ODg3MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODQyOTIsIC03OS4zODIyODAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83NzU2Y2FkMWY5Yjk0Mzk1YmI0ODFkNzkyYWI1YzZlOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzc1NmNhZDFmOWI5NDM5NWJiNDgxZDc5MmFiNWM2ZTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZpcnN0IENhbmFkaWFuIFBsYWNlLCBVbmRlcmdyb3VuZCBjaXR5LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2LnNldENvbnRlbnQoaHRtbF83NzU2Y2FkMWY5Yjk0Mzk1YmI0ODFkNzkyYWI1YzZlOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTUxMWI5YTdiNzM3NDhiYTg4NDQ0NGFjNzM3ODg4NzMuYmluZFBvcHVwKHBvcHVwXzhhYzFmYTVkODM1NDRiOTliMDkzNTcyNDMyMTNmNWM2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82YWFhN2ZhOGQ3MzQ0MTMxODQ1NjE2OWM5N2E0N2I5ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzY1MzYwMDAwMDAwNSwgLTc5LjUwNjk0MzZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2M2ODViN2NkODQ3MDQ2OWY4ODM2OTlhNmQ2OTdlNTJhID0gJChgPGRpdiBpZD0iaHRtbF9jNjg1YjdjZDg0NzA0NjlmODgzNjk5YTZkNjk3ZTUyYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VGhlIEtpbmdzd2F5LCBNb250Z29tZXJ5IFJvYWQsIE9sZCBNaWxsIE5vcnRoLCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEuc2V0Q29udGVudChodG1sX2M2ODViN2NkODQ3MDQ2OWY4ODM2OTlhNmQ2OTdlNTJhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82YWFhN2ZhOGQ3MzQ0MTMxODQ1NjE2OWM5N2E0N2I5ZS5iaW5kUG9wdXAocG9wdXBfZDcyNDUxOGVkMGY1NGMzMmI1MjdkNjczZDk2MGFmZjEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA1ZGY0ZDQyYThiYjQ0ODhiMzk4YzZhYTU4MDMxZGQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY1ODU5OSwgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZWY2YzAyZTg2ZDc0NmZjOTQzNDYzYjIxNmYyODQ5YSA9ICQoYDxkaXYgaWQ9Imh0bWxfN2VmNmMwMmU4NmQ3NDZmYzk0MzQ2M2IyMTZmMjg0OWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5LCBEb3dudG93biBUb3JvbnRvPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlLnNldENvbnRlbnQoaHRtbF83ZWY2YzAyZTg2ZDc0NmZjOTQzNDYzYjIxNmYyODQ5YSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDVkZjRkNDJhOGJiNDQ4OGIzOThjNmFhNTgwMzFkZDguYmluZFBvcHVwKHBvcHVwX2Q3MmI2M2UyYjQzMzQ4NjFiYjdlOGIzZTgzY2ZjNzZlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNjQwYmVmOGE0YWI0MWIwYWQxMWI3ZmE1YWI2YmEzYyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Mjc0MzksIC03OS4zMjE1NThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogImJsdWUiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF83Yzg2ZGNmMDFmMWI0OGMzOGU3MWRkNDZjYjEyNDdiOCk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzFhZjdhMTlhMTdhMjQ1NGZiMmRmYTBmZWFkYzI0MjI3ID0gJChgPGRpdiBpZD0iaHRtbF8xYWY3YTE5YTE3YTI0NTRmYjJkZmEwZmVhZGMyNDIyNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgcmVwbHkgbWFpbCBQcm9jZXNzaW5nIENlbnRyZSwgU291dGggQ2VudHJhbCBMZXR0ZXIgUHJvY2Vzc2luZyBQbGFudCBUb3JvbnRvLCBFYXN0IFRvcm9udG88L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYuc2V0Q29udGVudChodG1sXzFhZjdhMTlhMTdhMjQ1NGZiMmRmYTBmZWFkYzI0MjI3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNjQwYmVmOGE0YWI0MWIwYWQxMWI3ZmE1YWI2YmEzYy5iaW5kUG9wdXAocG9wdXBfYWQ5YzQwZDdhMDViNGVhYmE1OTRlNzIxY2NmYWJkMGYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4ODYzYjllZDI5ZTQ2OGQ4ODg4ODM2M2RmOTczZWM1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjM2MjU3OSwgLTc5LjQ5ODUwOTA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICJibHVlIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfN2M4NmRjZjAxZjFiNDhjMzhlNzFkZDQ2Y2IxMjQ3YjgpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mMWJiZjBhMGNlZDY0ZDA3YjI3NTBjNTI0YTIzYTIwZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZjFiYmYwYTBjZWQ2NGQwN2IyNzUwYzUyNGEyM2EyMGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk9sZCBNaWxsIFNvdXRoLCBLaW5nJiMzOTtzIE1pbGwgUGFyaywgU3VubnlsZWEsIEh1bWJlciBCYXksIE1pbWljbyBORSwgVGhlIFF1ZWVuc3dheSBFYXN0LCBSb3lhbCBZb3JrIFNvdXRoIEVhc3QsIEtpbmdzd2F5IFBhcmsgU291dGggRWFzdCwgRXRvYmljb2tlPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2LnNldENvbnRlbnQoaHRtbF9mMWJiZjBhMGNlZDY0ZDA3YjI3NTBjNTI0YTIzYTIwZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZjg4NjNiOWVkMjllNDY4ZDg4ODg4MzYzZGY5NzNlYzUuYmluZFBvcHVwKHBvcHVwX2M2MjVkOWNhODc5MzQ3OTM5NWFkYTIwYmRlMTdjMzE2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YzBhYzI0MzkyMWM0ODk1ODlhM2FiZmMxOTU0NWQ2OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYyODg0MDgsIC03OS41MjA5OTk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiYmx1ZSIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzdjODZkY2YwMWYxYjQ4YzM4ZTcxZGQ0NmNiMTI0N2I4KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wMzkzNjZmMjM0ZGY0ODA2YjhjNzBlNDkzMmI4YjQzOCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMmY5MDZjOTIxOTE4NDlhZDgzNDEwZGMxYjllOWU2ZTUgPSAkKGA8ZGl2IGlkPSJodG1sXzJmOTA2YzkyMTkxODQ5YWQ4MzQxMGRjMWI5ZTllNmU1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5NaW1pY28gTlcsIFRoZSBRdWVlbnN3YXkgV2VzdCwgU291dGggb2YgQmxvb3IsIEtpbmdzd2F5IFBhcmsgU291dGggV2VzdCwgUm95YWwgWW9yayBTb3V0aCBXZXN0LCBFdG9iaWNva2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDM5MzY2ZjIzNGRmNDgwNmI4YzcwZTQ5MzJiOGI0Mzguc2V0Q29udGVudChodG1sXzJmOTA2YzkyMTkxODQ5YWQ4MzQxMGRjMWI5ZTllNmU1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YzBhYzI0MzkyMWM0ODk1ODlhM2FiZmMxOTU0NWQ2OC5iaW5kUG9wdXAocG9wdXBfMDM5MzY2ZjIzNGRmNDgwNmI4YzcwZTQ5MzJiOGI0MzgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAo8L3NjcmlwdD4= onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
 812      ],
 813      "text/plain": [
 814       "<folium.folium.Map at 0x1a0657a4808>"
 815      ]
 816     },
 817     "execution_count": 89,
 818     "metadata": {},
 819     "output_type": "execute_result"
 820    }
 821   ],
 822   "source": [
 823    "import folium\n",
 824    "\n",
 825    "# create map of Toronto using latitude and longitude values\n",
 826    "map_Toronto = folium.Map(location=[latitude, longitude], zoom_start=10)\n",
 827    "\n",
 828    "# add markers to map\n",
 829    "for lat, lng, borough, neighborhood in zip(df['Latitude'], df['Longitude'], df['Borough'], df['Neighbourhood']):\n",
 830    "    label = '{}, {}'.format(neighborhood, borough)\n",
 831    "    label = folium.Popup(label, parse_html=True)\n",
 832    "    folium.CircleMarker(\n",
 833    "        [lat, lng],\n",
 834    "        radius=5,\n",
 835    "        popup=label,\n",
 836    "        color='blue',\n",
 837    "        fill=True,\n",
 838    "        fill_color='#3186cc',\n",
 839    "        fill_opacity=0.7,\n",
 840    "        ).add_to(map_Toronto)  \n",
 841    "    \n",
 842    "map_Toronto"
 843   ]
 844  },
 845  {
 846   "cell_type": "markdown",
 847   "metadata": {},
 848   "source": [
 849    "Define Foursquare parameters"
 850   ]
 851  },
 852  {
 853   "cell_type": "code",
 854   "execution_count": 90,
 855   "metadata": {},
 856   "outputs": [],
 857   "source": [
 858    "CLIENT_ID = 'MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN'\n",
 859    "CLIENT_SECRET = 'YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ'"
 860   ]
 861  },
 862  {
 863   "cell_type": "code",
 864   "execution_count": 91,
 865   "metadata": {},
 866   "outputs": [
 867    {
 868     "name": "stdout",
 869     "output_type": "stream",
 870     "text": [
 871      "Your credentails:\n",
 872      "CLIENT_ID: MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN\n",
 873      "CLIENT_SECRET:YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ\n"
 874     ]
 875    }
 876   ],
 877   "source": [
 878    "VERSION = '20180604' # Foursquare API version\n",
 879    "\n",
 880    "print('Your credentails:')\n",
 881    "print('CLIENT_ID: ' + CLIENT_ID)\n",
 882    "print('CLIENT_SECRET:' + CLIENT_SECRET)"
 883   ]
 884  },
 885  {
 886   "cell_type": "markdown",
 887   "metadata": {},
 888   "source": [
 889    "Explore the data, and get the venues in 500 meters range from our first entry"
 890   ]
 891  },
 892  {
 893   "cell_type": "code",
 894   "execution_count": 93,
 895   "metadata": {},
 896   "outputs": [
 897    {
 898     "name": "stdout",
 899     "output_type": "stream",
 900     "text": [
 901      "Latitude and longitude values of Parkwoods are 43.7532586, -79.3296565.\n"
 902     ]
 903    }
 904   ],
 905   "source": [
 906    "neighborhood_latitude = df.loc[0, 'Latitude'] # neighborhood latitude value\n",
 907    "neighborhood_longitude = df.loc[0, 'Longitude'] # neighborhood longitude value\n",
 908    "\n",
 909    "neighborhood_name = df.loc[0, 'Neighbourhood'] # neighborhood name\n",
 910    "\n",
 911    "print('Latitude and longitude values of {} are {}, {}.'.format(neighborhood_name, \n",
 912    "                                                               neighborhood_latitude, \n",
 913    "                                                               neighborhood_longitude))"
 914   ]
 915  },
 916  {
 917   "cell_type": "markdown",
 918   "metadata": {},
 919   "source": [
 920    "Create the GET request URL"
 921   ]
 922  },
 923  {
 924   "cell_type": "code",
 925   "execution_count": 94,
 926   "metadata": {},
 927   "outputs": [
 928    {
 929     "data": {
 930      "text/plain": [
 931       "'https://api.foursquare.com/v2/venues/explore?&client_id=MPMD3J0GGDV0HKDJFEDRK0USSGW0MQUD0DMN3C4ZAMWT2XTN&client_secret=YVCSGVSCX02EFWITMI3RDOTUSJEHV4APRMLBFCN5CKWXCTPJ&v=20180604&ll=43.7532586,-79.3296565&radius=500&limit=100'"
 932      ]
 933     },
 934     "execution_count": 94,
 935     "metadata": {},
 936     "output_type": "execute_result"
 937    }
 938   ],
 939   "source": [
 940    "LIMIT = 100\n",
 941    "radius = 500\n",
 942    "url = 'https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}'.format(\n",
 943    "    CLIENT_ID, \n",
 944    "    CLIENT_SECRET, \n",
 945    "    VERSION, \n",
 946    "    neighborhood_latitude, \n",
 947    "    neighborhood_longitude, \n",
 948    "    radius, \n",
 949    "    LIMIT)\n",
 950    "url"
 951   ]
 952  },
 953  {
 954   "cell_type": "code",
 955   "execution_count": 95,
 956   "metadata": {},
 957   "outputs": [
 958    {
 959     "data": {
 960      "text/plain": [
 961       "{'meta': {'code': 200, 'requestId': '5f1dab2fb0d9d01cac2a7fbc'},\n",
 962       " '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",
 963       "  'headerLocation': 'Parkwoods - Donalda',\n",
 964       "  'headerFullLocation': 'Parkwoods - Donalda, Toronto',\n",
 965       "  'headerLocationGranularity': 'neighborhood',\n",
 966       "  'totalResults': 2,\n",
 967       "  'suggestedBounds': {'ne': {'lat': 43.757758604500005,\n",
 968       "    'lng': -79.32343823984928},\n",
 969       "   'sw': {'lat': 43.7487585955, 'lng': -79.33587476015072}},\n",
 970       "  'groups': [{'type': 'Recommended Places',\n",
 971       "    'name': 'recommended',\n",
 972       "    'items': [{'reasons': {'count': 0,\n",
 973       "       'items': [{'summary': 'This spot is popular',\n",
 974       "         'type': 'general',\n",
 975       "         'reasonName': 'globalInteractionReason'}]},\n",
 976       "      'venue': {'id': '4e8d9dcdd5fbbbb6b3003c7b',\n",
 977       "       'name': 'Brookbanks Park',\n",
 978       "       'location': {'address': 'Toronto',\n",
 979       "        'lat': 43.751976046055574,\n",
 980       "        'lng': -79.33214044722958,\n",
 981       "        'labeledLatLngs': [{'label': 'display',\n",
 982       "          'lat': 43.751976046055574,\n",
 983       "          'lng': -79.33214044722958}],\n",
 984       "        'distance': 245,\n",
 985       "        'cc': 'CA',\n",
 986       "        'city': 'Toronto',\n",
 987       "        'state': 'ON',\n",
 988       "        'country': 'Canada',\n",
 989       "        'formattedAddress': ['Toronto', 'Toronto ON', 'Canada']},\n",
 990       "       'categories': [{'id': '4bf58dd8d48988d163941735',\n",
 991       "         'name': 'Park',\n",
 992       "         'pluralName': 'Parks',\n",
 993       "         'shortName': 'Park',\n",
 994       "         'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/parks_outdoors/park_',\n",
 995       "          'suffix': '.png'},\n",
 996       "         'primary': True}],\n",
 997       "       'photos': {'count': 0, 'groups': []}},\n",
 998       "      'referralId': 'e-0-4e8d9dcdd5fbbbb6b3003c7b-0'},\n",
 999       "     {'reasons': {'count': 0,\n",
1000       "       'items': [{'summary': 'This spot is popular',\n",
1001       "         'type': 'general',\n",
1002       "         'reasonName': 'globalInteractionReason'}]},\n",
1003       "      'venue': {'id': '4cb11e2075ebb60cd1c4caad',\n",
1004       "       'name': 'Variety Store',\n",
1005       "       'location': {'address': '29 Valley Woods Road',\n",
1006       "        'lat': 43.75197441585782,\n",
1007       "        'lng': -79.33311418516017,\n",
1008       "        'labeledLatLngs': [{'label': 'display',\n",
1009       "          'lat': 43.75197441585782,\n",
1010       "          'lng': -79.33311418516017}],\n",
1011       "        'distance': 312,\n",
1012       "        'cc': 'CA',\n",
1013       "        'city': 'Toronto',\n",
1014       "        'state': 'ON',\n",
1015       "        'country': 'Canada',\n",
1016       "        'formattedAddress': ['29 Valley Woods Road', 'Toronto ON', 'Canada']},\n",
1017       "       'categories': [{'id': '4bf58dd8d48988d1f9941735',\n",
1018       "         'name': 'Food & Drink Shop',\n",
1019       "         'pluralName': 'Food & Drink Shops',\n",
1020       "         'shortName': 'Food & Drink',\n",
1021       "         'icon': {'prefix': 'https://ss3.4sqi.net/img/categories_v2/shops/foodanddrink_',\n",
1022       "          'suffix': '.png'},\n",
1023       "         'primary': True}],\n",
1024       "       'photos': {'count': 0, 'groups': []}},\n",
1025       "      'referralId': 'e-0-4cb11e2075ebb60cd1c4caad-1'}]}]}}"
1026      ]
1027     },
1028     "execution_count": 95,
1029     "metadata": {},
1030     "output_type": "execute_result"
1031    }
1032   ],
1033   "source": [
1034    "results = requests.get(url).json()\n",
1035    "results"
1036   ]
1037  },
1038  {
1039   "cell_type": "code",
1040   "execution_count": 96,
1041   "metadata": {},
1042   "outputs": [],
1043   "source": [
1044    "# function that extracts the category of the venue\n",
1045    "def get_category_type(row):\n",
1046    "    try:\n",
1047    "        categories_list = row['categories']\n",
1048    "    except:\n",
1049    "        categories_list = row['venue.categories']\n",
1050    "        \n",
1051    "    if len(categories_list) == 0:\n",
1052    "        return None\n",
1053    "    else:\n",
1054    "        return categories_list[0]['name']"
1055   ]
1056  },
1057  {
1058   "cell_type": "code",
1059   "execution_count": 97,
1060   "metadata": {},
1061   "outputs": [
1062    {
1063     "name": "stderr",
1064     "output_type": "stream",
1065     "text": [
1066      "C:\\Users\\my_user\\anaconda3\\lib\\site-packages\\ipykernel_launcher.py:6: FutureWarning: pandas.io.json.json_normalize is deprecated, use pandas.json_normalize instead\n",
1067      "  \n"
1068     ]
1069    },
1070    {
1071     "data": {
1072      "text/html": [
1073       "<div>\n",
1074       "<style scoped>\n",
1075       "    .dataframe tbody tr th:only-of-type {\n",
1076       "        vertical-align: middle;\n",
1077       "    }\n",
1078       "\n",
1079       "    .dataframe tbody tr th {\n",
1080       "        vertical-align: top;\n",
1081       "    }\n",
1082       "\n",
1083       "    .dataframe thead th {\n",
1084       "        text-align: right;\n",
1085       "    }\n",
1086       "</style>\n",
1087       "<table border=\"1\" class=\"dataframe\">\n",
1088       "  <thead>\n",
1089       "    <tr style=\"text-align: right;\">\n",
1090       "      <th></th>\n",
1091       "      <th>name</th>\n",
1092       "      <th>categories</th>\n",
1093       "      <th>lat</th>\n",
1094       "      <th>lng</th>\n",
1095       "    </tr>\n",
1096       "  </thead>\n",
1097       "  <tbody>\n",
1098       "    <tr>\n",
1099       "      <th>0</th>\n",
1100       "      <td>Brookbanks Park</td>\n",
1101       "      <td>Park</td>\n",
1102       "      <td>43.751976</td>\n",
1103       "      <td>-79.332140</td>\n",
1104       "    </tr>\n",
1105       "    <tr>\n",
1106       "      <th>1</th>\n",
1107       "      <td>Variety Store</td>\n",
1108       "      <td>Food &amp; Drink Shop</td>\n",
1109       "      <td>43.751974</td>\n",
1110       "      <td>-79.333114</td>\n",
1111       "    </tr>\n",
1112       "  </tbody>\n",
1113       "</table>\n",
1114       "</div>"
1115      ],
1116      "text/plain": [
1117       "              name         categories        lat        lng\n",
1118       "0  Brookbanks Park               Park  43.751976 -79.332140\n",
1119       "1    Variety Store  Food & Drink Shop  43.751974 -79.333114"
1120      ]
1121     },
1122     "execution_count": 97,
1123     "metadata": {},
1124     "output_type": "execute_result"
1125    }
1126   ],
1127   "source": [
1128    "import json\n",
1129    "from pandas.io.json import json_normalize\n",
1130    "\n",
1131    "venues = results['response']['groups'][0]['items']\n",
1132    "    \n",
1133    "nearby_venues = json_normalize(venues) # flatten JSON\n",
1134    "\n",
1135    "# filter columns\n",
1136    "filtered_columns = ['venue.name', 'venue.categories', 'venue.location.lat', 'venue.location.lng']\n",
1137    "nearby_venues =nearby_venues.loc[:, filtered_columns]\n",
1138    "\n",
1139    "# filter the category for each row\n",
1140    "nearby_venues['venue.categories'] = nearby_venues.apply(get_category_type, axis=1)\n",
1141    "\n",
1142    "# clean columns\n",
1143    "nearby_venues.columns = [col.split(\".\")[-1] for col in nearby_venues.columns]\n",
1144    "\n",
1145    "nearby_venues.head()"
1146   ]
1147  },
1148  {
1149   "cell_type": "markdown",
1150   "metadata": {},
1151   "source": [
1152    "Generalize to obtain the venues from all neighbourhoods in Toronto"
1153   ]
1154  },
1155  {
1156   "cell_type": "code",
1157   "execution_count": 98,
1158   "metadata": {},
1159   "outputs": [],
1160   "source": [
1161    "def getNearbyVenues(names, latitudes, longitudes, radius=500):\n",
1162    "    \n",
1163    "    venues_list=[]\n",
1164    "    for name, lat, lng in zip(names, latitudes, longitudes):\n",
1165    "        print(name)\n",
1166    "            \n",
1167    "        # create the API request URL\n",
1168    "        url = 'https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}'.format(\n",
1169    "            CLIENT_ID, \n",
1170    "            CLIENT_SECRET, \n",
1171    "            VERSION, \n",
1172    "            lat, \n",
1173    "            lng, \n",
1174    "            radius, \n",
1175    "            LIMIT)\n",
1176    "            \n",
1177    "        # make the GET request\n",
1178    "        results = requests.get(url).json()[\"response\"]['groups'][0]['items']\n",
1179    "        \n",
1180    "        # return only relevant information for each nearby venue\n",
1181    "        venues_list.append([(\n",
1182    "            name, \n",
1183    "            lat, \n",
1184    "            lng, \n",
1185    "            v['venue']['name'], \n",
1186    "            v['venue']['location']['lat'], \n",
1187    "            v['venue']['location']['lng'],  \n",
1188    "            v['venue']['categories'][0]['name']) for v in results])\n",
1189    "\n",
1190    "    nearby_venues = pd.DataFrame([item for venue_list in venues_list for item in venue_list])\n",
1191    "    nearby_venues.columns = ['Neighbourhood', \n",
1192    "                  'Neighborhood Latitude', \n",
1193    "                  'Neighborhood Longitude', \n",
1194    "                  'Venue', \n",
1195    "                  'Venue Latitude', \n",
1196    "                  'Venue Longitude', \n",
1197    "                  'Venue Category']\n",
1198    "    \n",
1199    "    return(nearby_venues)"
1200   ]
1201  },
1202  {
1203   "cell_type": "code",
1204   "execution_count": 100,
1205   "metadata": {},
1206   "outputs": [
1207    {
1208     "name": "stdout",
1209     "output_type": "stream",
1210     "text": [
1211      "Parkwoods\n",
1212      "Victoria Village\n",
1213      "Regent Park, Harbourfront\n",
1214      "Lawrence Manor, Lawrence Heights\n",
1215      "Queen's Park, Ontario Provincial Government\n",
1216      "Islington Avenue, Humber Valley Village\n",
1217      "Malvern, Rouge\n",
1218      "Don Mills\n",
1219      "Parkview Hill, Woodbine Gardens\n",
1220      "Garden District, Ryerson\n",
1221      "Glencairn\n",
1222      "West Deane Park, Princess Gardens, Martin Grove, Islington, Cloverdale\n",
1223      "Rouge Hill, Port Union, Highland Creek\n",
1224      "Don Mills\n",
1225      "Woodbine Heights\n",
1226      "St. James Town\n",
1227      "Humewood-Cedarvale\n",
1228      "Eringate, Bloordale Gardens, Old Burnhamthorpe, Markland Wood\n",
1229      "Guildwood, Morningside, West Hill\n",
1230      "The Beaches\n",
1231      "Berczy Park\n",
1232      "Caledonia-Fairbanks\n",
1233      "Woburn\n",
1234      "Leaside\n",
1235      "Central Bay Street\n",
1236      "my_usertie\n",
1237      "Cedarbrae\n",
1238      "Hillcrest Village\n",
1239      "Bathurst Manor, Wilson Heights, Downsview North\n",
1240      "Thorncliffe Park\n",
1241      "Richmond, Adelaide, King\n",
1242      "Dufferin, Dovercourt Village\n",
1243      "Scarborough Village\n",
1244      "Fairview, Henry Farm, Oriole\n",
1245      "Northwood Park, York University\n",
1246      "East Toronto, Broadview North (Old East York)\n",
1247      "Harbourfront East, Union Station, Toronto Islands\n",
1248      "Little Portugal, Trinity\n",
1249      "Kennedy Park, Ionview, East Birchmount Park\n",
1250      "Bayview Village\n",
1251      "Downsview\n",
1252      "The Danforth West, Riverdale\n",
1253      "Toronto Dominion Centre, Design Exchange\n",
1254      "Brockton, Parkdale Village, Exhibition Place\n",
1255      "Golden Mile, Clairlea, Oakridge\n",
1256      "York Mills, Silver Hills\n",
1257      "Downsview\n",
1258      "India Bazaar, The Beaches West\n",
1259      "Commerce Court, Victoria Hotel\n",
1260      "North Park, Maple Leaf Park, Upwood Park\n",
1261      "Humber Summit\n",
1262      "Cliffside, Cliffcrest, Scarborough Village West\n",
1263      "Willowdale, Newtonbrook\n",
1264      "Downsview\n",
1265      "Studio District\n",
1266      "Bedford Park, Lawrence Manor East\n",
1267      "Del Ray, Mount Dennis, Keelsdale and Silverthorn\n",
1268      "Humberlea, Emery\n",
1269      "Birch Cliff, Cliffside West\n",
1270      "Willowdale, Willowdale East\n",
1271      "Downsview\n",
1272      "Lawrence Park\n",
1273      "Roselawn\n",
1274      "Runnymede, The Junction North\n",
1275      "Weston\n",
1276      "Dorset Park, Wexford Heights, Scarborough Town Centre\n",
1277      "York Mills West\n",
1278      "Davisville North\n",
1279      "Forest Hill North & West, Forest Hill Road Park\n",
1280      "High Park, The Junction South\n",
1281      "Westmount\n",
1282      "Wexford, Maryvale\n",
1283      "Willowdale, Willowdale West\n",
1284      "North Toronto West, Lawrence Park\n",
1285      "The Annex, North Midtown, Yorkville\n",
1286      "Parkdale, Roncesvalles\n",
1287      "Canada Post Gateway Processing Centre\n",
1288      "Kingsview Village, St. Phillips, Martin Grove Gardens, Richview Gardens\n",
1289      "Agincourt\n",
1290      "Davisville\n",
1291      "University of Toronto, Harbord\n",
1292      "Runnymede, Swansea\n",
1293      "Clarks Corners, Tam O'Shanter, Sullivan\n",
1294      "Moore Park, Summerhill East\n",
1295      "Kensington Market, Chinatown, Grange Park\n",
1296      "Milliken, Agincourt North, Steeles East, L'Amoreaux East\n",
1297      "Summerhill West, Rathnelly, South Hill, Forest Hill SE, Deer Park\n",
1298      "CN Tower, King and Spadina, Railway Lands, Harbourfront West, Bathurst Quay, South Niagara, Island airport\n",
1299      "New Toronto, Mimico South, Humber Bay Shores\n",
1300      "South Steeles, Silverstone, Humbergate, Jamestown, Mount Olive, Beaumond Heights, Thistletown, Albion Gardens\n",
1301      "Steeles West, L'Amoreaux West\n",
1302      "Rosedale\n",
1303      "Stn A PO Boxes\n",
1304      "Alderwood, Long Branch\n",
1305      "Northwest, West Humber - Clairville\n",
1306      "Upper Rouge\n",
1307      "St. James Town, Cabbagetown\n",
1308      "First Canadian Place, Underground city\n",
1309      "The Kingsway, Montgomery Road, Old Mill North\n",
1310      "Church and Wellesley\n",
1311      "Business reply mail Processing Centre, South Central Letter Processing Plant Toronto\n",
1312      "Old Mill South, King's Mill Park, Sunnylea, Humber Bay, Mimico NE, The Queensway East, Royal York South East, Kingsway Park South East\n",
1313      "Mimico NW, The Queensway West, South of Bloor, Kingsway Park South West, Royal York South West\n"
1314     ]
1315    }
1316   ],
1317   "source": [
1318    "toronto_venues = getNearbyVenues(names=df['Neighbourhood'],\n",
1319    "                                   latitudes=df['Latitude'],\n",
1320    "                                   longitudes=df['Longitude']\n",
1321    "                                  )"
1322   ]
1323  },
1324  {
1325   "cell_type": "markdown",
1326   "metadata": {},
1327   "source": [
1328    "Checking the size of df"
1329   ]
1330  },
1331  {
1332   "cell_type": "code",
1333   "execution_count": 101,
1334   "metadata": {},
1335   "outputs": [
1336    {
1337     "name": "stdout",
1338     "output_type": "stream",
1339     "text": [
1340      "(2153, 7)\n"
1341     ]
1342    },
1343    {
1344     "data": {
1345      "text/html": [
1346       "<div>\n",
1347       "<style scoped>\n",
1348       "    .dataframe tbody tr th:only-of-type {\n",
1349       "        vertical-align: middle;\n",
1350       "    }\n",
1351       "\n",
1352       "    .dataframe tbody tr th {\n",
1353       "        vertical-align: top;\n",
1354       "    }\n",
1355       "\n",
1356       "    .dataframe thead th {\n",
1357       "        text-align: right;\n",
1358       "    }\n",
1359       "</style>\n",
1360       "<table border=\"1\" class=\"dataframe\">\n",
1361       "  <thead>\n",
1362       "    <tr style=\"text-align: right;\">\n",
1363       "      <th></th>\n",
1364       "      <th>Neighbourhood</th>\n",
1365       "      <th>Neighborhood Latitude</th>\n",
1366       "      <th>Neighborhood Longitude</th>\n",
1367       "      <th>Venue</th>\n",
1368       "      <th>Venue Latitude</th>\n",
1369       "      <th>Venue Longitude</th>\n",
1370       "      <th>Venue Category</th>\n",
1371       "    </tr>\n",
1372       "  </thead>\n",
1373       "  <tbody>\n",
1374       "    <tr>\n",
1375       "      <th>0</th>\n",
1376       "      <td>Parkwoods</td>\n",
1377       "      <td>43.753259</td>\n",
1378       "      <td>-79.329656</td>\n",
1379       "      <td>Brookbanks Park</td>\n",
1380       "      <td>43.751976</td>\n",
1381       "      <td>-79.332140</td>\n",
1382       "      <td>Park</td>\n",
1383       "    </tr>\n",
1384       "    <tr>\n",
1385       "      <th>1</th>\n",
1386       "      <td>Parkwoods</td>\n",
1387       "      <td>43.753259</td>\n",
1388       "      <td>-79.329656</td>\n",
1389       "      <td>Variety Store</td>\n",
1390       "      <td>43.751974</td>\n",
1391       "      <td>-79.333114</td>\n",
1392       "      <td>Food &amp; Drink Shop</td>\n",
1393       "    </tr>\n",
1394       "    <tr>\n",
1395       "      <th>2</th>\n",
1396       "      <td>Victoria Village</td>\n",
1397       "      <td>43.725882</td>\n",
1398       "      <td>-79.315572</td>\n",
1399       "      <td>Victoria Village Arena</td>\n",
1400       "      <td>43.723481</td>\n",
1401       "      <td>-79.315635</td>\n",
1402       "      <td>Hockey Arena</td>\n",
1403       "    </tr>\n",
1404       "    <tr>\n",
1405       "      <th>3</th>\n",
1406       "      <td>Victoria Village</td>\n",
1407       "      <td>43.725882</td>\n",
1408       "      <td>-79.315572</td>\n",
1409       "      <td>Portugril</td>\n",
1410       "      <td>43.725819</td>\n",
1411       "      <td>-79.312785</td>\n",
1412       "      <td>Portuguese Restaurant</td>\n",
1413       "    </tr>\n",
1414       "    <tr>\n",
1415       "      <th>4</th>\n",
1416       "      <td>Victoria Village</td>\n",
1417       "      <td>43.725882</td>\n",
1418       "      <td>-79.315572</td>\n",
1419       "      <td>Tim Hortons</td>\n",
1420       "      <td>43.725517</td>\n",
1421       "      <td>-79.313103</td>\n",
1422       "      <td>Coffee Shop</td>\n",
1423       "    </tr>\n",
1424       "  </tbody>\n",
1425       "</table>\n",
1426       "</div>"
1427      ],
1428      "text/plain": [
1429       "      Neighbourhood  Neighborhood Latitude  Neighborhood Longitude  \\\n",
1430       "0         Parkwoods              43.753259              -79.329656   \n",
1431       "1         Parkwoods              43.753259              -79.329656   \n",
1432       "2  Victoria Village              43.725882              -79.315572   \n",
1433       "3  Victoria Village              43.725882              -79.315572   \n",
1434       "4  Victoria Village              43.725882              -79.315572   \n",
1435       "\n",
1436       "                    Venue  Venue Latitude  Venue Longitude  \\\n",
1437       "0         Brookbanks Park       43.751976       -79.332140   \n",
1438       "1           Variety Store       43.751974       -79.333114   \n",
1439       "2  Victoria Village Arena       43.723481       -79.315635   \n",
1440       "3               Portugril       43.725819       -79.312785   \n",
1441       "4             Tim Hortons       43.725517       -79.313103   \n",
1442       "\n",
1443       "          Venue Category  \n",
1444       "0                   Park  \n",
1445       "1      Food & Drink Shop  \n",
1446       "2           Hockey Arena  \n",
1447       "3  Portuguese Restaurant  \n",
1448       "4            Coffee Shop  "
1449      ]
1450     },
1451     "execution_count": 101,
1452     "metadata": {},
1453     "output_type": "execute_result"
1454    }
1455   ],
1456   "source": [
1457    "print(toronto_venues.shape)\n",
1458    "toronto_venues.head()"
1459   ]
1460  },
1461  {
1462   "cell_type": "markdown",
1463   "metadata": {},
1464   "source": [
1465    "Checking how many venues there are for each venue"
1466   ]
1467  },
1468  {
1469   "cell_type": "code",
1470   "execution_count": 102,
1471   "metadata": {},
1472   "outputs": [
1473    {
1474     "data": {
1475      "text/html": [
1476       "<div>\n",
1477       "<style scoped>\n",
1478       "    .dataframe tbody tr th:only-of-type {\n",
1479       "        vertical-align: middle;\n",
1480       "    }\n",
1481       "\n",
1482       "    .dataframe tbody tr th {\n",
1483       "        vertical-align: top;\n",
1484       "    }\n",
1485       "\n",
1486       "    .dataframe thead th {\n",
1487       "        text-align: right;\n",
1488       "    }\n",
1489       "</style>\n",
1490       "<table border=\"1\" class=\"dataframe\">\n",
1491       "  <thead>\n",
1492       "    <tr style=\"text-align: right;\">\n",
1493       "      <th></th>\n",
1494       "      <th>Neighborhood Latitude</th>\n",
1495       "      <th>Neighborhood Longitude</th>\n",
1496       "      <th>Venue</th>\n",
1497       "      <th>Venue Latitude</th>\n",
1498       "      <th>Venue Longitude</th>\n",
1499       "      <th>Venue Category</th>\n",
1500       "    </tr>\n",
1501       "    <tr>\n",
1502       "      <th>Neighbourhood</th>\n",
1503       "      <th></th>\n",
1504       "      <th></th>\n",
1505       "      <th></th>\n",
1506       "      <th></th>\n",
1507       "      <th></th>\n",
1508       "      <th></th>\n",
1509       "    </tr>\n",
1510       "  </thead>\n",
1511       "  <tbody>\n",
1512       "    <tr>\n",
1513       "      <th>Agincourt</th>\n",
1514       "      <td>4</td>\n",
1515       "      <td>4</td>\n",
1516       "      <td>4</td>\n",
1517       "      <td>4</td>\n",
1518       "      <td>4</td>\n",
1519       "      <td>4</td>\n",
1520       "    </tr>\n",
1521       "    <tr>\n",
1522       "      <th>Alderwood, Long Branch</th>\n",
1523       "      <td>8</td>\n",
1524       "      <td>8</td>\n",
1525       "      <td>8</td>\n",
1526       "      <td>8</td>\n",
1527       "      <td>8</td>\n",
1528       "      <td>8</td>\n",
1529       "    </tr>\n",
1530       "    <tr>\n",
1531       "      <th>Bathurst Manor, Wilson Heights, Downsview North</th>\n",
1532       "      <td>21</td>\n",
1533       "      <td>21</td>\n",
1534       "      <td>21</td>\n",
1535       "      <td>21</td>\n",
1536       "      <td>21</td>\n",
1537       "      <td>21</td>\n",
1538       "    </tr>\n",
1539       "    <tr>\n",
1540       "      <th>Bayview Village</th>\n",
1541       "      <td>4</td>\n",
1542       "      <td>4</td>\n",
1543       "      <td>4</td>\n",
1544       "      <td>4</td>\n",
1545       "      <td>4</td>\n",
1546       "      <td>4</td>\n",
1547       "    </tr>\n",
1548       "    <tr>\n",
1549       "      <th>Bedford Park, Lawrence Manor East</th>\n",
1550       "      <td>25</td>\n",
1551       "      <td>25</td>\n",
1552       "      <td>25</td>\n",
1553       "      <td>25</td>\n",
1554       "      <td>25</td>\n",
1555       "      <td>25</td>\n",
1556       "    </tr>\n",
1557       "    <tr>\n",
1558       "      <th>...</th>\n",
1559       "      <td>...</td>\n",
1560       "      <td>...</td>\n",
1561       "      <td>...</td>\n",
1562       "      <td>...</td>\n",
1563       "      <td>...</td>\n",
1564       "      <td>...</td>\n",
1565       "    </tr>\n",
1566       "    <tr>\n",
1567       "      <th>Willowdale, Willowdale East</th>\n",
1568       "      <td>34</td>\n",
1569       "      <td>34</td>\n",
1570       "      <td>34</td>\n",
1571       "      <td>34</td>\n",
1572       "      <td>34</td>\n",
1573       "      <td>34</td>\n",
1574       "    </tr>\n",
1575       "    <tr>\n",
1576       "      <th>Willowdale, Willowdale West</th>\n",
1577       "      <td>6</td>\n",
1578       "      <td>6</td>\n",
1579       "      <td>6</td>\n",
1580       "      <td>6</td>\n",
1581       "      <td>6</td>\n",
1582       "      <td>6</td>\n",
1583       "    </tr>\n",
1584       "    <tr>\n",
1585       "      <th>Woburn</th>\n",
1586       "      <td>4</td>\n",
1587       "      <td>4</td>\n",
1588       "      <td>4</td>\n",
1589       "      <td>4</td>\n",
1590       "      <td>4</td>\n",
1591       "      <td>4</td>\n",
1592       "    </tr>\n",
1593       "    <tr>\n",
1594       "      <th>Woodbine Heights</th>\n",
1595       "      <td>9</td>\n",
1596       "      <td>9</td>\n",
1597       "      <td>9</td>\n",
1598       "      <td>9</td>\n",
1599       "      <td>9</td>\n",
1600       "      <td>9</td>\n",
1601       "    </tr>\n",
1602       "    <tr>\n",
1603       "      <th>York Mills West</th>\n",
1604       "      <td>3</td>\n",
1605       "      <td>3</td>\n",
1606       "      <td>3</td>\n",
1607       "      <td>3</td>\n",
1608       "      <td>3</td>\n",
1609       "      <td>3</td>\n",
1610       "    </tr>\n",
1611       "  </tbody>\n",
1612       "</table>\n",
1613       "<p>96 rows × 6 columns</p>\n",
1614       "</div>"
1615      ],
1616      "text/plain": [
1617       "                                                 Neighborhood Latitude  \\\n",
1618       "Neighbourhood                                                            \n",
1619       "Agincourt                                                            4   \n",
1620       "Alderwood, Long Branch                                               8   \n",
1621       "Bathurst Manor, Wilson Heights, Downsview North                     21   \n",
1622       "Bayview Village                                                      4   \n",
1623       "Bedford Park, Lawrence Manor East                                   25   \n",
1624       "...                                                                ...   \n",
1625       "Willowdale, Willowdale East                                         34   \n",
1626       "Willowdale, Willowdale West                                          6   \n",
1627       "Woburn                                                               4   \n",
1628       "Woodbine Heights                                                     9   \n",
1629       "York Mills West                                                      3   \n",
1630       "\n",
1631       "                                                 Neighborhood Longitude  \\\n",
1632       "Neighbourhood                                                             \n",
1633       "Agincourt                                                             4   \n",
1634       "Alderwood, Long Branch                                                8   \n",
1635       "Bathurst Manor, Wilson Heights, Downsview North                      21   \n",
1636       "Bayview Village                                                       4   \n",
1637       "Bedford Park, Lawrence Manor East                                    25   \n",
1638       "...                                                                 ...   \n",
1639       "Willowdale, Willowdale East                                          34   \n",
1640       "Willowdale, Willowdale West                                           6   \n",
1641       "Woburn                                                                4   \n",
1642       "Woodbine Heights                                                      9   \n",
1643       "York Mills West                                                       3   \n",
1644       "\n",
1645       "                                                 Venue  Venue Latitude  \\\n",
1646       "Neighbourhood                                                            \n",
1647       "Agincourt                                            4               4   \n",
1648       "Alderwood, Long Branch                               8               8   \n",
1649       "Bathurst Manor, Wilson Heights, Downsview North     21              21   \n",
1650       "Bayview Village                                      4               4   \n",
1651       "Bedford Park, Lawrence Manor East                   25              25   \n",
1652       "...                                                ...             ...   \n",
1653       "Willowdale, Willowdale East                         34              34   \n",
1654       "Willowdale, Willowdale West                          6               6   \n",
1655       "Woburn                                               4               4   \n",
1656       "Woodbine Heights                                     9               9   \n",
1657       "York Mills West                                      3               3   \n",
1658       "\n",
1659       "                                                 Venue Longitude  \\\n",
1660       "Neighbourhood                                                      \n",
1661       "Agincourt                                                      4   \n",
1662       "Alderwood, Long Branch                                         8   \n",
1663       "Bathurst Manor, Wilson Heights, Downsview North               21   \n",
1664       "Bayview Village                                                4   \n",
1665       "Bedford Park, Lawrence Manor East                             25   \n",
1666       "...                                                          ...   \n",
1667       "Willowdale, Willowdale East                                   34   \n",
1668       "Willowdale, Willowdale West                                    6   \n",
1669       "Woburn                                                         4   \n",
1670       "Woodbine Heights                                               9   \n",
1671       "York Mills West                                                3   \n",
1672       "\n",
1673       "                                                 Venue Category  \n",
1674       "Neighbourhood                                                    \n",
1675       "Agincourt                                                     4  \n",
1676       "Alderwood, Long Branch                                        8  \n",
1677       "Bathurst Manor, Wilson Heights, Downsview North              21  \n",
1678       "Bayview Village                                               4  \n",
1679       "Bedford Park, Lawrence Manor East                            25  \n",
1680       "...                                                         ...  \n",
1681       "Willowdale, Willowdale East                                  34  \n",
1682       "Willowdale, Willowdale West                                   6  \n",
1683       "Woburn                                                        4  \n",
1684       "Woodbine Heights                                              9  \n",
1685       "York Mills West                                               3  \n",
1686       "\n",
1687       "[96 rows x 6 columns]"
1688      ]
1689     },
1690     "execution_count": 102,
1691     "metadata": {},
1692     "output_type": "execute_result"
1693    }
1694   ],
1695   "source": [
1696    "toronto_venues.groupby('Neighbourhood').count()"
1697   ]
1698  },
1699  {
1700   "cell_type": "markdown",
1701   "metadata": {},
1702   "source": [
1703    "How many categorys can we find?"
1704   ]
1705  },
1706  {
1707   "cell_type": "code",
1708   "execution_count": 103,
1709   "metadata": {},
1710   "outputs": [
1711    {
1712     "data": {
1713      "text/html": [
1714       "<div>\n",
1715       "<style scoped>\n",
1716       "    .dataframe tbody tr th:only-of-type {\n",
1717       "        vertical-align: middle;\n",
1718       "    }\n",
1719       "\n",
1720       "    .dataframe tbody tr th {\n",
1721       "        vertical-align: top;\n",
1722       "    }\n",
1723       "\n",
1724       "    .dataframe thead th {\n",
1725       "        text-align: right;\n",
1726       "    }\n",
1727       "</style>\n",
1728       "<table border=\"1\" class=\"dataframe\">\n",
1729       "  <thead>\n",
1730       "    <tr style=\"text-align: right;\">\n",
1731       "      <th></th>\n",
1732       "      <th>Neighbourhood</th>\n",
1733       "      <th>Accessories Store</th>\n",
1734       "      <th>Afghan Restaurant</th>\n",
1735       "      <th>Airport</th>\n",
1736       "      <th>Airport Food Court</th>\n",
1737       "      <th>Airport Lounge</th>\n",
1738       "      <th>Airport Service</th>\n",
1739       "      <th>Airport Terminal</th>\n",
1740       "      <th>American Restaurant</th>\n",
1741       "      <th>Antique Shop</th>\n",
1742       "      <th>...</th>\n",
1743       "      <th>Vegetarian / Vegan Restaurant</th>\n",
1744       "      <th>Video Game Store</th>\n",
1745       "      <th>Video Store</th>\n",
1746       "      <th>Vietnamese Restaurant</th>\n",
1747       "      <th>Warehouse Store</th>\n",
1748       "      <th>Wine Bar</th>\n",
1749       "      <th>Wine Shop</th>\n",
1750       "      <th>Wings Joint</th>\n",
1751       "      <th>Women's Store</th>\n",
1752       "      <th>Yoga Studio</th>\n",
1753       "    </tr>\n",
1754       "  </thead>\n",
1755       "  <tbody>\n",
1756       "    <tr>\n",
1757       "      <th>0</th>\n",
1758       "      <td>Parkwoods</td>\n",
1759       "      <td>0</td>\n",
1760       "      <td>0</td>\n",
1761       "      <td>0</td>\n",
1762       "      <td>0</td>\n",
1763       "      <td>0</td>\n",
1764       "      <td>0</td>\n",
1765       "      <td>0</td>\n",
1766       "      <td>0</td>\n",
1767       "      <td>0</td>\n",
1768       "      <td>...</td>\n",
1769       "      <td>0</td>\n",
1770       "      <td>0</td>\n",
1771       "      <td>0</td>\n",
1772       "      <td>0</td>\n",
1773       "      <td>0</td>\n",
1774       "      <td>0</td>\n",
1775       "      <td>0</td>\n",
1776       "      <td>0</td>\n",
1777       "      <td>0</td>\n",
1778       "      <td>0</td>\n",
1779       "    </tr>\n",
1780       "    <tr>\n",
1781       "      <th>1</th>\n",
1782       "      <td>Parkwoods</td>\n",
1783       "      <td>0</td>\n",
1784       "      <td>0</td>\n",
1785       "      <td>0</td>\n",
1786       "      <td>0</td>\n",
1787       "      <td>0</td>\n",
1788       "      <td>0</td>\n",
1789       "      <td>0</td>\n",
1790       "      <td>0</td>\n",
1791       "      <td>0</td>\n",
1792       "      <td>...</td>\n",
1793       "      <td>0</td>\n",
1794       "      <td>0</td>\n",
1795       "      <td>0</td>\n",
1796       "      <td>0</td>\n",
1797       "      <td>0</td>\n",
1798       "      <td>0</td>\n",
1799       "      <td>0</td>\n",
1800       "      <td>0</td>\n",
1801       "      <td>0</td>\n",
1802       "      <td>0</td>\n",
1803       "    </tr>\n",
1804       "    <tr>\n",
1805       "      <th>2</th>\n",
1806       "      <td>Victoria Village</td>\n",
1807       "      <td>0</td>\n",
1808       "      <td>0</td>\n",
1809       "      <td>0</td>\n",
1810       "      <td>0</td>\n",
1811       "      <td>0</td>\n",
1812       "      <td>0</td>\n",
1813       "      <td>0</td>\n",
1814       "      <td>0</td>\n",
1815       "      <td>0</td>\n",
1816       "      <td>...</td>\n",
1817       "      <td>0</td>\n",
1818       "      <td>0</td>\n",
1819       "      <td>0</td>\n",
1820       "      <td>0</td>\n",
1821       "      <td>0</td>\n",
1822       "      <td>0</td>\n",
1823       "      <td>0</td>\n",
1824       "      <td>0</td>\n",
1825       "      <td>0</td>\n",
1826       "      <td>0</td>\n",
1827       "    </tr>\n",
1828       "    <tr>\n",
1829       "      <th>3</th>\n",
1830       "      <td>Victoria Village</td>\n",
1831       "      <td>0</td>\n",
1832       "      <td>0</td>\n",
1833       "      <td>0</td>\n",
1834       "      <td>0</td>\n",
1835       "      <td>0</td>\n",
1836       "      <td>0</td>\n",
1837       "      <td>0</td>\n",
1838       "      <td>0</td>\n",
1839       "      <td>0</td>\n",
1840       "      <td>...</td>\n",
1841       "      <td>0</td>\n",
1842       "      <td>0</td>\n",
1843       "      <td>0</td>\n",
1844       "      <td>0</td>\n",
1845       "      <td>0</td>\n",
1846       "      <td>0</td>\n",
1847       "      <td>0</td>\n",
1848       "      <td>0</td>\n",
1849       "      <td>0</td>\n",
1850       "      <td>0</td>\n",
1851       "    </tr>\n",
1852       "    <tr>\n",
1853       "      <th>4</th>\n",
1854       "      <td>Victoria Village</td>\n",
1855       "      <td>0</td>\n",
1856       "      <td>0</td>\n",
1857       "      <td>0</td>\n",
1858       "      <td>0</td>\n",
1859       "      <td>0</td>\n",
1860       "      <td>0</td>\n",
1861       "      <td>0</td>\n",
1862       "      <td>0</td>\n",
1863       "      <td>0</td>\n",
1864       "      <td>...</td>\n",
1865       "      <td>0</td>\n",
1866       "      <td>0</td>\n",
1867       "      <td>0</td>\n",
1868       "      <td>0</td>\n",
1869       "      <td>0</td>\n",
1870       "      <td>0</td>\n",
1871       "      <td>0</td>\n",
1872       "      <td>0</td>\n",
1873       "      <td>0</td>\n",
1874       "      <td>0</td>\n",
1875       "    </tr>\n",
1876       "  </tbody>\n",
1877       "</table>\n",
1878       "<p>5 rows × 270 columns</p>\n",
1879       "</div>"
1880      ],
1881      "text/plain": [
1882       "      Neighbourhood  Accessories Store  Afghan Restaurant  Airport  \\\n",
1883       "0         Parkwoods                  0                  0        0   \n",
1884       "1         Parkwoods                  0                  0        0   \n",
1885       "2  Victoria Village                  0                  0        0   \n",
1886       "3  Victoria Village                  0                  0        0   \n",
1887       "4  Victoria Village                  0                  0        0   \n",
1888       "\n",
1889       "   Airport Food Court  Airport Lounge  Airport Service  Airport Terminal  \\\n",
1890       "0                   0               0                0                 0   \n",
1891       "1                   0               0                0                 0   \n",
1892       "2                   0               0                0                 0   \n",
1893       "3                   0               0                0                 0   \n",
1894       "4                   0               0                0                 0   \n",
1895       "\n",
1896       "   American Restaurant  Antique Shop  ...  Vegetarian / Vegan Restaurant  \\\n",
1897       "0                    0             0  ...                              0   \n",
1898       "1                    0             0  ...                              0   \n",
1899       "2                    0             0  ...                              0   \n",
1900       "3                    0             0  ...                              0   \n",
1901       "4                    0             0  ...                              0   \n",
1902       "\n",
1903       "   Video Game Store  Video Store  Vietnamese Restaurant  Warehouse Store  \\\n",
1904       "0                 0            0                      0                0   \n",
1905       "1                 0            0                      0                0   \n",
1906       "2                 0            0                      0                0   \n",
1907       "3                 0            0                      0                0   \n",
1908       "4                 0            0                      0                0   \n",
1909       "\n",
1910       "   Wine Bar  Wine Shop  Wings Joint  Women's Store  Yoga Studio  \n",
1911       "0         0          0            0              0            0  \n",
1912       "1         0          0            0              0            0  \n",
1913       "2         0          0            0              0            0  \n",
1914       "3         0          0            0              0            0  \n",
1915       "4         0          0            0              0            0  \n",
1916       "\n",
1917       "[5 rows x 270 columns]"
1918      ]
1919     },
1920     "execution_count": 103,
1921     "metadata": {},
1922     "output_type": "execute_result"
1923    }
1924   ],
1925   "source": [
1926    "# one hot encoding\n",
1927    "toronto_onehot = pd.get_dummies(toronto_venues[['Venue Category']], prefix=\"\", prefix_sep=\"\")\n",
1928    "\n",
1929    "# add neighborhood column back to dataframe\n",
1930    "toronto_onehot['Neighbourhood'] = toronto_venues['Neighbourhood'] \n",
1931    "\n",
1932    "# move neighborhood column to the first column\n",
1933    "fixed_columns = [toronto_onehot.columns[-1]] + list(toronto_onehot.columns[:-1])\n",
1934    "toronto_onehot = toronto_onehot[fixed_columns]\n",
1935    "\n",
1936    "toronto_onehot.head()"
1937   ]
1938  },
1939  {
1940   "cell_type": "code",
1941   "execution_count": 104,
1942   "metadata": {},
1943   "outputs": [
1944    {
1945     "data": {
1946      "text/plain": [
1947       "(2153, 270)"
1948      ]
1949     },
1950     "execution_count": 104,
1951     "metadata": {},
1952     "output_type": "execute_result"
1953    }
1954   ],
1955   "source": [
1956    "toronto_onehot.shape"
1957   ]
1958  },
1959  {
1960   "cell_type": "code",
1961   "execution_count": 105,
1962   "metadata": {},
1963   "outputs": [
1964    {
1965     "data": {
1966      "text/html": [
1967       "<div>\n",
1968       "<style scoped>\n",
1969       "    .dataframe tbody tr th:only-of-type {\n",
1970       "        vertical-align: middle;\n",
1971       "    }\n",
1972       "\n",
1973       "    .dataframe tbody tr th {\n",
1974       "        vertical-align: top;\n",
1975       "    }\n",
1976       "\n",
1977       "    .dataframe thead th {\n",
1978       "        text-align: right;\n",
1979       "    }\n",
1980       "</style>\n",
1981       "<table border=\"1\" class=\"dataframe\">\n",
1982       "  <thead>\n",
1983       "    <tr style=\"text-align: right;\">\n",
1984       "      <th></th>\n",
1985       "      <th>Neighbourhood</th>\n",
1986       "      <th>Accessories Store</th>\n",
1987       "      <th>Afghan Restaurant</th>\n",
1988       "      <th>Airport</th>\n",
1989       "      <th>Airport Food Court</th>\n",
1990       "      <th>Airport Lounge</th>\n",
1991       "      <th>Airport Service</th>\n",
1992       "      <th>Airport Terminal</th>\n",
1993       "      <th>American Restaurant</th>\n",
1994       "      <th>Antique Shop</th>\n",
1995       "      <th>...</th>\n",
1996       "      <th>Vegetarian / Vegan Restaurant</th>\n",
1997       "      <th>Video Game Store</th>\n",
1998       "      <th>Video Store</th>\n",
1999       "      <th>Vietnamese Restaurant</th>\n",
2000       "      <th>Warehouse Store</th>\n",
2001       "      <th>Wine Bar</th>\n",
2002       "      <th>Wine Shop</th>\n",
2003       "      <th>Wings Joint</th>\n",
2004       "      <th>Women's Store</th>\n",
2005       "      <th>Yoga Studio</th>\n",
2006       "    </tr>\n",
2007       "  </thead>\n",
2008       "  <tbody>\n",
2009       "    <tr>\n",
2010       "      <th>0</th>\n",
2011       "      <td>Agincourt</td>\n",
2012       "      <td>0.0</td>\n",
2013       "      <td>0.0</td>\n",
2014       "      <td>0.0</td>\n",
2015       "      <td>0.0</td>\n",
2016       "      <td>0.0</td>\n",
2017       "      <td>0.0</td>\n",
2018       "      <td>0.0</td>\n",
2019       "      <td>0.00</td>\n",
2020       "      <td>0.0</td>\n",
2021       "      <td>...</td>\n",
2022       "      <td>0.0</td>\n",
2023       "      <td>0.0</td>\n",
2024       "      <td>0.0</td>\n",
2025       "      <td>0.0</td>\n",
2026       "      <td>0.0</td>\n",
2027       "      <td>0.0</td>\n",
2028       "      <td>0.0</td>\n",
2029       "      <td>0.0</td>\n",
2030       "      <td>0.00</td>\n",
2031       "      <td>0.0</td>\n",
2032       "    </tr>\n",
2033       "    <tr>\n",
2034       "      <th>1</th>\n",
2035       "      <td>Alderwood, Long Branch</td>\n",
2036       "      <td>0.0</td>\n",
2037       "      <td>0.0</td>\n",
2038       "      <td>0.0</td>\n",
2039       "      <td>0.0</td>\n",
2040       "      <td>0.0</td>\n",
2041       "      <td>0.0</td>\n",
2042       "      <td>0.0</td>\n",
2043       "      <td>0.00</td>\n",
2044       "      <td>0.0</td>\n",
2045       "      <td>...</td>\n",
2046       "      <td>0.0</td>\n",
2047       "      <td>0.0</td>\n",
2048       "      <td>0.0</td>\n",
2049       "      <td>0.0</td>\n",
2050       "      <td>0.0</td>\n",
2051       "      <td>0.0</td>\n",
2052       "      <td>0.0</td>\n",
2053       "      <td>0.0</td>\n",
2054       "      <td>0.00</td>\n",
2055       "      <td>0.0</td>\n",
2056       "    </tr>\n",
2057       "    <tr>\n",
2058       "      <th>2</th>\n",
2059       "      <td>Bathurst Manor, Wilson Heights, Downsview North</td>\n",
2060       "      <td>0.0</td>\n",
2061       "      <td>0.0</td>\n",
2062       "      <td>0.0</td>\n",
2063       "      <td>0.0</td>\n",
2064       "      <td>0.0</td>\n",
2065       "      <td>0.0</td>\n",
2066       "      <td>0.0</td>\n",
2067       "      <td>0.00</td>\n",
2068       "      <td>0.0</td>\n",
2069       "      <td>...</td>\n",
2070       "      <td>0.0</td>\n",
2071       "      <td>0.0</td>\n",
2072       "      <td>0.0</td>\n",
2073       "      <td>0.0</td>\n",
2074       "      <td>0.0</td>\n",
2075       "      <td>0.0</td>\n",
2076       "      <td>0.0</td>\n",
2077       "      <td>0.0</td>\n",
2078       "      <td>0.00</td>\n",
2079       "      <td>0.0</td>\n",
2080       "    </tr>\n",
2081       "    <tr>\n",
2082       "      <th>3</th>\n",
2083       "      <td>Bayview Village</td>\n",
2084       "      <td>0.0</td>\n",
2085       "      <td>0.0</td>\n",
2086       "      <td>0.0</td>\n",
2087       "      <td>0.0</td>\n",
2088       "      <td>0.0</td>\n",
2089       "      <td>0.0</td>\n",
2090       "      <td>0.0</td>\n",
2091       "      <td>0.00</td>\n",
2092       "      <td>0.0</td>\n",
2093       "      <td>...</td>\n",
2094       "      <td>0.0</td>\n",
2095       "      <td>0.0</td>\n",
2096       "      <td>0.0</td>\n",
2097       "      <td>0.0</td>\n",
2098       "      <td>0.0</td>\n",
2099       "      <td>0.0</td>\n",
2100       "      <td>0.0</td>\n",
2101       "      <td>0.0</td>\n",
2102       "      <td>0.00</td>\n",
2103       "      <td>0.0</td>\n",
2104       "    </tr>\n",
2105       "    <tr>\n",
2106       "      <th>4</th>\n",
2107       "      <td>Bedford Park, Lawrence Manor East</td>\n",
2108       "      <td>0.0</td>\n",
2109       "      <td>0.0</td>\n",
2110       "      <td>0.0</td>\n",
2111       "      <td>0.0</td>\n",
2112       "      <td>0.0</td>\n",
2113       "      <td>0.0</td>\n",
2114       "      <td>0.0</td>\n",
2115       "      <td>0.04</td>\n",
2116       "      <td>0.0</td>\n",
2117       "      <td>...</td>\n",
2118       "      <td>0.0</td>\n",
2119       "      <td>0.0</td>\n",
2120       "      <td>0.0</td>\n",
2121       "      <td>0.0</td>\n",
2122       "      <td>0.0</td>\n",
2123       "      <td>0.0</td>\n",
2124       "      <td>0.0</td>\n",
2125       "      <td>0.0</td>\n",
2126       "      <td>0.04</td>\n",
2127       "      <td>0.0</td>\n",
2128       "    </tr>\n",
2129       "  </tbody>\n",
2130       "</table>\n",
2131       "<p>5 rows × 270 columns</p>\n",
2132       "</div>"
2133      ],
2134      "text/plain": [
2135       "                                     Neighbourhood  Accessories Store  \\\n",
2136       "0                                        Agincourt                0.0   \n",
2137       "1                           Alderwood, Long Branch                0.0   \n",
2138       "2  Bathurst Manor, Wilson Heights, Downsview North                0.0   \n",
2139       "3                                  Bayview Village                0.0   \n",
2140       "4                Bedford Park, Lawrence Manor East                0.0   \n",
2141       "\n",
2142       "   Afghan Restaurant  Airport  Airport Food Court  Airport Lounge  \\\n",
2143       "0                0.0      0.0                 0.0             0.0   \n",
2144       "1                0.0      0.0                 0.0             0.0   \n",
2145       "2                0.0      0.0                 0.0             0.0   \n",
2146       "3                0.0      0.0                 0.0             0.0   \n",
2147       "4                0.0      0.0                 0.0             0.0   \n",
2148       "\n",
2149       "   Airport Service  Airport Terminal  American Restaurant  Antique Shop  ...  \\\n",
2150       "0              0.0               0.0                 0.00           0.0  ...   \n",
2151       "1              0.0               0.0                 0.00           0.0  ...   \n",
2152       "2              0.0               0.0                 0.00           0.0  ...   \n",
2153       "3              0.0               0.0                 0.00           0.0  ...   \n",
2154       "4              0.0               0.0                 0.04           0.0  ...   \n",
2155       "\n",
2156       "   Vegetarian / Vegan Restaurant  Video Game Store  Video Store  \\\n",
2157       "0                            0.0               0.0          0.0   \n",
2158       "1                            0.0               0.0          0.0   \n",
2159       "2                            0.0               0.0          0.0   \n",
2160       "3                            0.0               0.0          0.0   \n",
2161       "4                            0.0               0.0          0.0   \n",
2162       "\n",
2163       "   Vietnamese Restaurant  Warehouse Store  Wine Bar  Wine Shop  Wings Joint  \\\n",
2164       "0                    0.0              0.0       0.0        0.0          0.0   \n",
2165       "1                    0.0              0.0       0.0        0.0          0.0   \n",
2166       "2                    0.0              0.0       0.0        0.0          0.0   \n",
2167       "3                    0.0              0.0       0.0        0.0          0.0   \n",
2168       "4                    0.0              0.0       0.0        0.0          0.0   \n",
2169       "\n",
2170       "   Women's Store  Yoga Studio  \n",
2171       "0           0.00          0.0  \n",
2172       "1           0.00          0.0  \n",
2173       "2           0.00          0.0  \n",
2174       "3           0.00          0.0  \n",
2175       "4           0.04          0.0  \n",
2176       "\n",
2177       "[5 rows x 270 columns]"
2178      ]
2179     },
2180     "execution_count": 105,
2181     "metadata": {},
2182     "output_type": "execute_result"
2183    }
2184   ],
2185   "source": [
2186    "toronto_grouped = toronto_onehot.groupby('Neighbourhood').mean().reset_index()\n",
2187    "toronto_grouped.head()"
2188   ]
2189  },
2190  {
2191   "cell_type": "code",
2192   "execution_count": 106,
2193   "metadata": {},
2194   "outputs": [
2195    {
2196     "data": {
2197      "text/plain": [
2198       "(96, 270)"
2199      ]
2200     },
2201     "execution_count": 106,
2202     "metadata": {},
2203     "output_type": "execute_result"
2204    }
2205   ],
2206   "source": [
2207    "toronto_grouped.shape"
2208   ]
2209  },
2210  {
2211   "cell_type": "markdown",
2212   "metadata": {},
2213   "source": [
2214    "Getting the top 10 for each neighbourhood"
2215   ]
2216  },
2217  {
2218   "cell_type": "code",
2219   "execution_count": 107,
2220   "metadata": {},
2221   "outputs": [],
2222   "source": [
2223    "def return_most_common_venues(row, num_top_venues):\n",
2224    "    row_categories = row.iloc[1:]\n",
2225    "    row_categories_sorted = row_categories.sort_values(ascending=False)\n",
2226    "    \n",
2227    "    return row_categories_sorted.index.values[0:num_top_venues]"
2228   ]
2229  },
2230  {
2231   "cell_type": "code",
2232   "execution_count": 108,
2233   "metadata": {},
2234   "outputs": [
2235    {
2236     "data": {
2237      "text/html": [
2238       "<div>\n",
2239       "<style scoped>\n",
2240       "    .dataframe tbody tr th:only-of-type {\n",
2241       "        vertical-align: middle;\n",
2242       "    }\n",
2243       "\n",
2244       "    .dataframe tbody tr th {\n",
2245       "        vertical-align: top;\n",
2246       "    }\n",
2247       "\n",
2248       "    .dataframe thead th {\n",
2249       "        text-align: right;\n",
2250       "    }\n",
2251       "</style>\n",
2252       "<table border=\"1\" class=\"dataframe\">\n",
2253       "  <thead>\n",
2254       "    <tr style=\"text-align: right;\">\n",
2255       "      <th></th>\n",
2256       "      <th>Neighbourhood</th>\n",
2257       "      <th>1st Most Common Venue</th>\n",
2258       "      <th>2nd Most Common Venue</th>\n",
2259       "      <th>3rd Most Common Venue</th>\n",
2260       "      <th>4th Most Common Venue</th>\n",
2261       "      <th>5th Most Common Venue</th>\n",
2262       "      <th>6th Most Common Venue</th>\n",
2263       "      <th>7th Most Common Venue</th>\n",
2264       "      <th>8th Most Common Venue</th>\n",
2265       "      <th>9th Most Common Venue</th>\n",
2266       "      <th>10th Most Common Venue</th>\n",
2267       "    </tr>\n",
2268       "  </thead>\n",
2269       "  <tbody>\n",
2270       "    <tr>\n",
2271       "      <th>0</th>\n",
2272       "      <td>Agincourt</td>\n",
2273       "      <td>Lounge</td>\n",
2274       "      <td>Latin American Restaurant</td>\n",
2275       "      <td>Skating Rink</td>\n",
2276       "      <td>Breakfast Spot</td>\n",
2277       "      <td>Donut Shop</td>\n",
2278       "      <td>Diner</td>\n",
2279       "      <td>Discount Store</td>\n",
2280       "      <td>Distribution Center</td>\n",
2281       "      <td>Dog Run</td>\n",
2282       "      <td>Doner Restaurant</td>\n",
2283       "    </tr>\n",
2284       "    <tr>\n",
2285       "      <th>1</th>\n",
2286       "      <td>Alderwood, Long Branch</td>\n",
2287       "      <td>Pizza Place</td>\n",
2288       "      <td>Pharmacy</td>\n",
2289       "      <td>Sandwich Place</td>\n",
2290       "      <td>Dance Studio</td>\n",
2291       "      <td>Coffee Shop</td>\n",
2292       "      <td>Pub</td>\n",
2293       "      <td>Gym</td>\n",
2294       "      <td>Airport Terminal</td>\n",
2295       "      <td>Falafel Restaurant</td>\n",
2296       "      <td>Event Space</td>\n",
2297       "    </tr>\n",
2298       "    <tr>\n",
2299       "      <th>2</th>\n",
2300       "      <td>Bathurst Manor, Wilson Heights, Downsview North</td>\n",
2301       "      <td>Coffee Shop</td>\n",
2302       "      <td>Bank</td>\n",
2303       "      <td>Frozen Yogurt Shop</td>\n",
2304       "      <td>Bridal Shop</td>\n",
2305       "      <td>Sandwich Place</td>\n",
2306       "      <td>Diner</td>\n",
2307       "      <td>Restaurant</td>\n",
2308       "      <td>Deli / Bodega</td>\n",
2309       "      <td>Middle Eastern Restaurant</td>\n",
2310       "      <td>Supermarket</td>\n",
2311       "    </tr>\n",
2312       "    <tr>\n",
2313       "      <th>3</th>\n",
2314       "      <td>Bayview Village</td>\n",
2315       "      <td>Café</td>\n",
2316       "      <td>Bank</td>\n",
2317       "      <td>Chinese Restaurant</td>\n",
2318       "      <td>Japanese Restaurant</td>\n",
2319       "      <td>Yoga Studio</td>\n",
2320       "      <td>Diner</td>\n",
2321       "      <td>Discount Store</td>\n",
2322       "      <td>Distribution Center</td>\n",
2323       "      <td>Dog Run</td>\n",
2324       "      <td>Doner Restaurant</td>\n",
2325       "    </tr>\n",
2326       "    <tr>\n",
2327       "      <th>4</th>\n",
2328       "      <td>Bedford Park, Lawrence Manor East</td>\n",
2329       "      <td>Sandwich Place</td>\n",
2330       "      <td>Restaurant</td>\n",
2331       "      <td>Italian Restaurant</td>\n",
2332       "      <td>Coffee Shop</td>\n",
2333       "      <td>Liquor Store</td>\n",
2334       "      <td>Thai Restaurant</td>\n",
2335       "      <td>Café</td>\n",
2336       "      <td>Pub</td>\n",
2337       "      <td>Butcher</td>\n",
2338       "      <td>Sushi Restaurant</td>\n",
2339       "    </tr>\n",
2340       "  </tbody>\n",
2341       "</table>\n",
2342       "</div>"
2343      ],
2344      "text/plain": [
2345       "                                     Neighbourhood 1st Most Common Venue  \\\n",
2346       "0                                        Agincourt                Lounge   \n",
2347       "1                           Alderwood, Long Branch           Pizza Place   \n",
2348       "2  Bathurst Manor, Wilson Heights, Downsview North           Coffee Shop   \n",
2349       "3                                  Bayview Village                  Café   \n",
2350       "4                Bedford Park, Lawrence Manor East        Sandwich Place   \n",
2351       "\n",
2352       "       2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue  \\\n",
2353       "0  Latin American Restaurant          Skating Rink        Breakfast Spot   \n",
2354       "1                   Pharmacy        Sandwich Place          Dance Studio   \n",
2355       "2                       Bank    Frozen Yogurt Shop           Bridal Shop   \n",
2356       "3                       Bank    Chinese Restaurant   Japanese Restaurant   \n",
2357       "4                 Restaurant    Italian Restaurant           Coffee Shop   \n",
2358       "\n",
2359       "  5th Most Common Venue 6th Most Common Venue 7th Most Common Venue  \\\n",
2360       "0            Donut Shop                 Diner        Discount Store   \n",
2361       "1           Coffee Shop                   Pub                   Gym   \n",
2362       "2        Sandwich Place                 Diner            Restaurant   \n",
2363       "3           Yoga Studio                 Diner        Discount Store   \n",
2364       "4          Liquor Store       Thai Restaurant                  Café   \n",
2365       "\n",
2366       "  8th Most Common Venue      9th Most Common Venue 10th Most Common Venue  \n",
2367       "0   Distribution Center                    Dog Run       Doner Restaurant  \n",
2368       "1      Airport Terminal         Falafel Restaurant            Event Space  \n",
2369       "2         Deli / Bodega  Middle Eastern Restaurant            Supermarket  \n",
2370       "3   Distribution Center                    Dog Run       Doner Restaurant  \n",
2371       "4                   Pub                    Butcher       Sushi Restaurant  "
2372      ]
2373     },
2374     "execution_count": 108,
2375     "metadata": {},
2376     "output_type": "execute_result"
2377    }
2378   ],
2379   "source": [
2380    "import numpy as np\n",
2381    "num_top_venues = 10\n",
2382    "\n",
2383    "indicators = ['st', 'nd', 'rd']\n",
2384    "\n",
2385    "# create columns according to number of top venues\n",
2386    "columns = ['Neighbourhood']\n",
2387    "for ind in np.arange(num_top_venues):\n",
2388    "    try:\n",
2389    "        columns.append('{}{} Most Common Venue'.format(ind+1, indicators[ind]))\n",
2390    "    except:\n",
2391    "        columns.append('{}th Most Common Venue'.format(ind+1))\n",
2392    "\n",
2393    "# create a new dataframe\n",
2394    "neighborhoods_venues_sorted = pd.DataFrame(columns=columns)\n",
2395    "neighborhoods_venues_sorted['Neighbourhood'] = toronto_grouped['Neighbourhood']\n",
2396    "\n",
2397    "for ind in np.arange(toronto_grouped.shape[0]):\n",
2398    "    neighborhoods_venues_sorted.iloc[ind, 1:] = return_most_common_venues(toronto_grouped.iloc[ind, :], num_top_venues)\n",
2399    "\n",
2400    "neighborhoods_venues_sorted.head()"
2401   ]
2402  },
2403  {
2404   "cell_type": "markdown",
2405   "metadata": {},
2406   "source": [
2407    "Clustering Neighborhoods"
2408   ]
2409  },
2410  {
2411   "cell_type": "code",
2412   "execution_count": 109,
2413   "metadata": {},
2414   "outputs": [
2415    {
2416     "data": {
2417      "text/plain": [
2418       "array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])"
2419      ]
2420     },
2421     "execution_count": 109,
2422     "metadata": {},
2423     "output_type": "execute_result"
2424    }
2425   ],
2426   "source": [
2427    "# import k-means from clustering stage\n",
2428    "from sklearn.cluster import KMeans\n",
2429    "\n",
2430    "# set number of clusters\n",
2431    "kclusters = 5\n",
2432    "\n",
2433    "toronto_grouped_clustering = toronto_grouped.drop('Neighbourhood', 1)\n",
2434    "\n",
2435    "# run k-means clustering\n",
2436    "kmeans = KMeans(n_clusters=kclusters, random_state=0).fit(toronto_grouped_clustering)\n",
2437    "\n",
2438    "# check cluster labels generated for each row in the dataframe\n",
2439    "kmeans.labels_[0:10]"
2440   ]
2441  },
2442  {
2443   "cell_type": "markdown",
2444   "metadata": {},
2445   "source": [
2446    "Merge the dataframe with the top 10 and the cluster for each neighbourhood"
2447   ]
2448  },
2449  {
2450   "cell_type": "code",
2451   "execution_count": 121,
2452   "metadata": {},
2453   "outputs": [
2454    {
2455     "data": {
2456      "text/html": [
2457       "<div>\n",
2458       "<style scoped>\n",
2459       "    .dataframe tbody tr th:only-of-type {\n",
2460       "        vertical-align: middle;\n",
2461       "    }\n",
2462       "\n",
2463       "    .dataframe tbody tr th {\n",
2464       "        vertical-align: top;\n",
2465       "    }\n",
2466       "\n",
2467       "    .dataframe thead th {\n",
2468       "        text-align: right;\n",
2469       "    }\n",
2470       "</style>\n",
2471       "<table border=\"1\" class=\"dataframe\">\n",
2472       "  <thead>\n",
2473       "    <tr style=\"text-align: right;\">\n",
2474       "      <th></th>\n",
2475       "      <th>Postal Code</th>\n",
2476       "      <th>Borough</th>\n",
2477       "      <th>Neighbourhood</th>\n",
2478       "      <th>Latitude</th>\n",
2479       "      <th>Longitude</th>\n",
2480       "    </tr>\n",
2481       "  </thead>\n",
2482       "  <tbody>\n",
2483       "    <tr>\n",
2484       "      <th>0</th>\n",
2485       "      <td>M3A</td>\n",
2486       "      <td>North York</td>\n",
2487       "      <td>Parkwoods</td>\n",
2488       "      <td>43.753259</td>\n",
2489       "      <td>-79.329656</td>\n",
2490       "    </tr>\n",
2491       "    <tr>\n",
2492       "      <th>1</th>\n",
2493       "      <td>M4A</td>\n",
2494       "      <td>North York</td>\n",
2495       "      <td>Victoria Village</td>\n",
2496       "      <td>43.725882</td>\n",
2497       "      <td>-79.315572</td>\n",
2498       "    </tr>\n",
2499       "    <tr>\n",
2500       "      <th>2</th>\n",
2501       "      <td>M5A</td>\n",
2502       "      <td>Downtown Toronto</td>\n",
2503       "      <td>Regent Park, Harbourfront</td>\n",
2504       "      <td>43.654260</td>\n",
2505       "      <td>-79.360636</td>\n",
2506       "    </tr>\n",
2507       "    <tr>\n",
2508       "      <th>3</th>\n",
2509       "      <td>M6A</td>\n",
2510       "      <td>North York</td>\n",
2511       "      <td>Lawrence Manor, Lawrence Heights</td>\n",
2512       "      <td>43.718518</td>\n",
2513       "      <td>-79.464763</td>\n",
2514       "    </tr>\n",
2515       "    <tr>\n",
2516       "      <th>4</th>\n",
2517       "      <td>M7A</td>\n",
2518       "      <td>Downtown Toronto</td>\n",
2519       "      <td>Queen's Park, Ontario Provincial Government</td>\n",
2520       "      <td>43.662301</td>\n",
2521       "      <td>-79.389494</td>\n",
2522       "    </tr>\n",
2523       "    <tr>\n",
2524       "      <th>...</th>\n",
2525       "      <td>...</td>\n",
2526       "      <td>...</td>\n",
2527       "      <td>...</td>\n",
2528       "      <td>...</td>\n",
2529       "      <td>...</td>\n",
2530       "    </tr>\n",
2531       "    <tr>\n",
2532       "      <th>98</th>\n",
2533       "      <td>M8X</td>\n",
2534       "      <td>Etobicoke</td>\n",
2535       "      <td>The Kingsway, Montgomery Road, Old Mill North</td>\n",
2536       "      <td>43.653654</td>\n",
2537       "      <td>-79.506944</td>\n",
2538       "    </tr>\n",
2539       "    <tr>\n",
2540       "      <th>99</th>\n",
2541       "      <td>M4Y</td>\n",
2542       "      <td>Downtown Toronto</td>\n",
2543       "      <td>Church and Wellesley</td>\n",
2544       "      <td>43.665860</td>\n",
2545       "      <td>-79.383160</td>\n",
2546       "    </tr>\n",
2547       "    <tr>\n",
2548       "      <th>100</th>\n",
2549       "      <td>M7Y</td>\n",
2550       "      <td>East Toronto</td>\n",
2551       "      <td>Business reply mail Processing Centre, South C...</td>\n",
2552       "      <td>43.662744</td>\n",
2553       "      <td>-79.321558</td>\n",
2554       "    </tr>\n",
2555       "    <tr>\n",
2556       "      <th>101</th>\n",
2557       "      <td>M8Y</td>\n",
2558       "      <td>Etobicoke</td>\n",
2559       "      <td>Old Mill South, King's Mill Park, Sunnylea, Hu...</td>\n",
2560       "      <td>43.636258</td>\n",
2561       "      <td>-79.498509</td>\n",
2562       "    </tr>\n",
2563       "    <tr>\n",
2564       "      <th>102</th>\n",
2565       "      <td>M8Z</td>\n",
2566       "      <td>Etobicoke</td>\n",
2567       "      <td>Mimico NW, The Queensway West, South of Bloor,...</td>\n",
2568       "      <td>43.628841</td>\n",
2569       "      <td>-79.520999</td>\n",
2570       "    </tr>\n",
2571       "  </tbody>\n",
2572       "</table>\n",
2573       "<p>103 rows × 5 columns</p>\n",
2574       "</div>"
2575      ],
2576      "text/plain": [
2577       "    Postal Code           Borough  \\\n",
2578       "0           M3A        North York   \n",
2579       "1           M4A        North York   \n",
2580       "2           M5A  Downtown Toronto   \n",
2581       "3           M6A        North York   \n",
2582       "4           M7A  Downtown Toronto   \n",
2583       "..          ...               ...   \n",
2584       "98          M8X         Etobicoke   \n",
2585       "99          M4Y  Downtown Toronto   \n",
2586       "100         M7Y      East Toronto   \n",
2587       "101         M8Y         Etobicoke   \n",
2588       "102         M8Z         Etobicoke   \n",
2589       "\n",
2590       "                                         Neighbourhood   Latitude  Longitude  \n",
2591       "0                                            Parkwoods  43.753259 -79.329656  \n",
2592       "1                                     Victoria Village  43.725882 -79.315572  \n",
2593       "2                            Regent Park, Harbourfront  43.654260 -79.360636  \n",
2594       "3                     Lawrence Manor, Lawrence Heights  43.718518 -79.464763  \n",
2595       "4          Queen's Park, Ontario Provincial Government  43.662301 -79.389494  \n",
2596       "..                                                 ...        ...        ...  \n",
2597       "98       The Kingsway, Montgomery Road, Old Mill North  43.653654 -79.506944  \n",
2598       "99                                Church and Wellesley  43.665860 -79.383160  \n",
2599       "100  Business reply mail Processing Centre, South C...  43.662744 -79.321558  \n",
2600       "101  Old Mill South, King's Mill Park, Sunnylea, Hu...  43.636258 -79.498509  \n",
2601       "102  Mimico NW, The Queensway West, South of Bloor,...  43.628841 -79.520999  \n",
2602       "\n",
2603       "[103 rows x 5 columns]"
2604      ]
2605     },
2606     "execution_count": 121,
2607     "metadata": {},
2608     "output_type": "execute_result"
2609    }
2610   ],
2611   "source": [
2612    "df"
2613   ]
2614  },
2615  {
2616   "cell_type": "code",
2617   "execution_count": 113,
2618   "metadata": {},
2619   "outputs": [
2620    {
2621     "data": {
2622      "text/html": [
2623       "<div>\n",
2624       "<style scoped>\n",
2625       "    .dataframe tbody tr th:only-of-type {\n",
2626       "        vertical-align: middle;\n",
2627       "    }\n",
2628       "\n",
2629       "    .dataframe tbody tr th {\n",
2630       "        vertical-align: top;\n",
2631       "    }\n",
2632       "\n",
2633       "    .dataframe thead th {\n",
2634       "        text-align: right;\n",
2635       "    }\n",
2636       "</style>\n",
2637       "<table border=\"1\" class=\"dataframe\">\n",
2638       "  <thead>\n",
2639       "    <tr style=\"text-align: right;\">\n",
2640       "      <th></th>\n",
2641       "      <th>Postal Code</th>\n",
2642       "      <th>Borough</th>\n",
2643       "      <th>Neighbourhood</th>\n",
2644       "      <th>Latitude</th>\n",
2645       "      <th>Longitude</th>\n",
2646       "      <th>Cluster Labels</th>\n",
2647       "      <th>1st Most Common Venue</th>\n",
2648       "      <th>2nd Most Common Venue</th>\n",
2649       "      <th>3rd Most Common Venue</th>\n",
2650       "      <th>4th Most Common Venue</th>\n",
2651       "      <th>5th Most Common Venue</th>\n",
2652       "      <th>6th Most Common Venue</th>\n",
2653       "      <th>7th Most Common Venue</th>\n",
2654       "      <th>8th Most Common Venue</th>\n",
2655       "      <th>9th Most Common Venue</th>\n",
2656       "      <th>10th Most Common Venue</th>\n",
2657       "    </tr>\n",
2658       "  </thead>\n",
2659       "  <tbody>\n",
2660       "    <tr>\n",
2661       "      <th>5</th>\n",
2662       "      <td>M9A</td>\n",
2663       "      <td>Etobicoke</td>\n",
2664       "      <td>Islington Avenue, Humber Valley Village</td>\n",
2665       "      <td>43.667856</td>\n",
2666       "      <td>-79.532242</td>\n",
2667       "      <td>NaN</td>\n",
2668       "      <td>NaN</td>\n",
2669       "      <td>NaN</td>\n",
2670       "      <td>NaN</td>\n",
2671       "      <td>NaN</td>\n",
2672       "      <td>NaN</td>\n",
2673       "      <td>NaN</td>\n",
2674       "      <td>NaN</td>\n",
2675       "      <td>NaN</td>\n",
2676       "      <td>NaN</td>\n",
2677       "      <td>NaN</td>\n",
2678       "    </tr>\n",
2679       "    <tr>\n",
2680       "      <th>45</th>\n",
2681       "      <td>M2L</td>\n",
2682       "      <td>North York</td>\n",
2683       "      <td>York Mills, Silver Hills</td>\n",
2684       "      <td>43.757490</td>\n",
2685       "      <td>-79.374714</td>\n",
2686       "      <td>NaN</td>\n",
2687       "      <td>NaN</td>\n",
2688       "      <td>NaN</td>\n",
2689       "      <td>NaN</td>\n",
2690       "      <td>NaN</td>\n",
2691       "      <td>NaN</td>\n",
2692       "      <td>NaN</td>\n",
2693       "      <td>NaN</td>\n",
2694       "      <td>NaN</td>\n",
2695       "      <td>NaN</td>\n",
2696       "      <td>NaN</td>\n",
2697       "    </tr>\n",
2698       "    <tr>\n",
2699       "      <th>95</th>\n",
2700       "      <td>M1X</td>\n",
2701       "      <td>Scarborough</td>\n",
2702       "      <td>Upper Rouge</td>\n",
2703       "      <td>43.836125</td>\n",
2704       "      <td>-79.205636</td>\n",
2705       "      <td>NaN</td>\n",
2706       "      <td>NaN</td>\n",
2707       "      <td>NaN</td>\n",
2708       "      <td>NaN</td>\n",
2709       "      <td>NaN</td>\n",
2710       "      <td>NaN</td>\n",
2711       "      <td>NaN</td>\n",
2712       "      <td>NaN</td>\n",
2713       "      <td>NaN</td>\n",
2714       "      <td>NaN</td>\n",
2715       "      <td>NaN</td>\n",
2716       "    </tr>\n",
2717       "  </tbody>\n",
2718       "</table>\n",
2719       "</div>"
2720      ],
2721      "text/plain": [
2722       "   Postal Code      Borough                            Neighbourhood  \\\n",
2723       "5          M9A    Etobicoke  Islington Avenue, Humber Valley Village   \n",
2724       "45         M2L   North York                 York Mills, Silver Hills   \n",
2725       "95         M1X  Scarborough                              Upper Rouge   \n",
2726       "\n",
2727       "     Latitude  Longitude  Cluster Labels 1st Most Common Venue  \\\n",
2728       "5   43.667856 -79.532242             NaN                   NaN   \n",
2729       "45  43.757490 -79.374714             NaN                   NaN   \n",
2730       "95  43.836125 -79.205636             NaN                   NaN   \n",
2731       "\n",
2732       "   2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue  \\\n",
2733       "5                    NaN                   NaN                   NaN   \n",
2734       "45                   NaN                   NaN                   NaN   \n",
2735       "95                   NaN                   NaN                   NaN   \n",
2736       "\n",
2737       "   5th Most Common Venue 6th Most Common Venue 7th Most Common Venue  \\\n",
2738       "5                    NaN                   NaN                   NaN   \n",
2739       "45                   NaN                   NaN                   NaN   \n",
2740       "95                   NaN                   NaN                   NaN   \n",
2741       "\n",
2742       "   8th Most Common Venue 9th Most Common Venue 10th Most Common Venue  \n",
2743       "5                    NaN                   NaN                    NaN  \n",
2744       "45                   NaN                   NaN                    NaN  \n",
2745       "95                   NaN                   NaN                    NaN  "
2746      ]
2747     },
2748     "execution_count": 113,
2749     "metadata": {},
2750     "output_type": "execute_result"
2751    }
2752   ],
2753   "source": [
2754    "toronto_merged[toronto_merged['Cluster Labels'].isnull()]"
2755   ]
2756  },
2757  {
2758   "cell_type": "markdown",
2759   "metadata": {},
2760   "source": [
2761    "Plot the clusters in the map"
2762   ]
2763  },
2764  {
2765   "cell_type": "code",
2766   "execution_count": 115,
2767   "metadata": {},
2768   "outputs": [
2769    {
2770     "data": {
2771      "text/html": [
2772       "<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><span style=\"color:#565656\">Make this Notebook Trusted to load map: File -> Trust Notebook</span><iframe src=\"about:blank\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgCiAgICAgICAgPHNjcmlwdD4KICAgICAgICAgICAgTF9OT19UT1VDSCA9IGZhbHNlOwogICAgICAgICAgICBMX0RJU0FCTEVfM0QgPSBmYWxzZTsKICAgICAgICA8L3NjcmlwdD4KICAgIAogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY29kZS5qcXVlcnkuY29tL2pxdWVyeS0xLjEyLjQubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9qcy9ib290c3RyYXAubWluLmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5qcyI+PC9zY3JpcHQ+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vbGVhZmxldEAxLjYuMC9kaXN0L2xlYWZsZXQuY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vYm9vdHN0cmFwLzMuMi4wL2Nzcy9ib290c3RyYXAubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLXRoZW1lLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9mb250LWF3ZXNvbWUvNC42LjMvY3NzL2ZvbnQtYXdlc29tZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL0xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLzIuMC4yL2xlYWZsZXQuYXdlc29tZS1tYXJrZXJzLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3Jhd2Nkbi5naXRoYWNrLmNvbS9weXRob24tdmlzdWFsaXphdGlvbi9mb2xpdW0vbWFzdGVyL2ZvbGl1bS90ZW1wbGF0ZXMvbGVhZmxldC5hd2Vzb21lLnJvdGF0ZS5jc3MiLz4KICAgIDxzdHlsZT5odG1sLCBib2R5IHt3aWR0aDogMTAwJTtoZWlnaHQ6IDEwMCU7bWFyZ2luOiAwO3BhZGRpbmc6IDA7fTwvc3R5bGU+CiAgICA8c3R5bGU+I21hcCB7cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7Ym90dG9tOjA7cmlnaHQ6MDtsZWZ0OjA7fTwvc3R5bGU+CiAgICAKICAgICAgICAgICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwKICAgICAgICAgICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgICAgICAgICAgPHN0eWxlPgogICAgICAgICAgICAgICAgI21hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSB7CiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlOwogICAgICAgICAgICAgICAgICAgIHdpZHRoOiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICAgICAgbGVmdDogMC4wJTsKICAgICAgICAgICAgICAgICAgICB0b3A6IDAuMCU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIDwvc3R5bGU+CiAgICAgICAgCjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImZvbGl1bS1tYXAiIGlkPSJtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUiID48L2Rpdj4KICAgICAgICAKPC9ib2R5Pgo8c2NyaXB0PiAgICAKICAgIAogICAgICAgICAgICB2YXIgbWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1ID0gTC5tYXAoCiAgICAgICAgICAgICAgICAibWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1IiwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjZW50ZXI6IFs0My42NTM0ODE3LCAtNzkuMzgzOTM0N10sCiAgICAgICAgICAgICAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICAgICAgICAgICAgICB6b29tOiAxMSwKICAgICAgICAgICAgICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBwcmVmZXJDYW52YXM6IGZhbHNlLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwoKICAgICAgICAgICAgCgogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyX2I0NTFjODgyYmM3YzQ5YWI5ZmJhOTdhMmFkMzE5OGJhID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAiaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmciLAogICAgICAgICAgICAgICAgeyJhdHRyaWJ1dGlvbiI6ICJEYXRhIGJ5IFx1MDAyNmNvcHk7IFx1MDAzY2EgaHJlZj1cImh0dHA6Ly9vcGVuc3RyZWV0bWFwLm9yZ1wiXHUwMDNlT3BlblN0cmVldE1hcFx1MDAzYy9hXHUwMDNlLCB1bmRlciBcdTAwM2NhIGhyZWY9XCJodHRwOi8vd3d3Lm9wZW5zdHJlZXRtYXAub3JnL2NvcHlyaWdodFwiXHUwMDNlT0RiTFx1MDAzYy9hXHUwMDNlLiIsICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwgIm1heE5hdGl2ZVpvb20iOiAxOCwgIm1heFpvb20iOiAxOCwgIm1pblpvb20iOiAwLCAibm9XcmFwIjogZmFsc2UsICJvcGFjaXR5IjogMSwgInN1YmRvbWFpbnMiOiAiYWJjIiwgInRtcyI6IGZhbHNlfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTEyOTY4MDgzYzc2NDZhYWJmZWJjNTRlNzhmNjc1YTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NTMyNTg2LCAtNzkuMzI5NjU2NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82YzRhMTk2ZGFhZjk0NTgzOWUxZDVkZTI1MjNmNmNmYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNmE4MDNhOWE0YzI4NDZlYmFmYzg4MjQ0MmFlNTQyZmQgPSAkKGA8ZGl2IGlkPSJodG1sXzZhODAzYTlhNGMyODQ2ZWJhZmM4ODI0NDJhZTU0MmZkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrd29vZHMgQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNmM0YTE5NmRhYWY5NDU4MzllMWQ1ZGUyNTIzZjZjZmMuc2V0Q29udGVudChodG1sXzZhODAzYTlhNGMyODQ2ZWJhZmM4ODI0NDJhZTU0MmZkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MTI5NjgwODNjNzY0NmFhYmZlYmM1NGU3OGY2NzVhNS5iaW5kUG9wdXAocG9wdXBfNmM0YTE5NmRhYWY5NDU4MzllMWQ1ZGUyNTIzZjZjZmMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UzNGMyNjFjNjM5ZTQ4NjBiYjQ2Mzg3MTRmZmFmOGMyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI1ODgyMjk5OTk5OTk1LCAtNzkuMzE1NTcxNTk5OTk5OThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWM0OWQ4YTMxOWQ1NDg3NGE5MTcxZTI1MjUwMjc3NWIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzY5Y2ViY2JkY2FhYTQyNTFiNzg3ZjMxMzc5NzhmZjdlID0gJChgPGRpdiBpZD0iaHRtbF82OWNlYmNiZGNhYWE0MjUxYjc4N2YzMTM3OTc4ZmY3ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+VmljdG9yaWEgVmlsbGFnZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lYzQ5ZDhhMzE5ZDU0ODc0YTkxNzFlMjUyNTAyNzc1Yi5zZXRDb250ZW50KGh0bWxfNjljZWJjYmRjYWFhNDI1MWI3ODdmMzEzNzk3OGZmN2UpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2UzNGMyNjFjNjM5ZTQ4NjBiYjQ2Mzg3MTRmZmFmOGMyLmJpbmRQb3B1cChwb3B1cF9lYzQ5ZDhhMzE5ZDU0ODc0YTkxNzFlMjUyNTAyNzc1YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzU0ZmZkNGZhMzQ4NDBhMDlmODM3N2E0NzEzYjU4YjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTQyNTk5LCAtNzkuMzYwNjM1OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMDVkOTM1ZjE2YzI0MjI3YmE0MmFhNDdmN2Y1ZWU4YiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzU5MWE2ZjBlOWU3NGU5MDgyODBiYTIwYWQ0YTNiOGQgPSAkKGA8ZGl2IGlkPSJodG1sXzM1OTFhNmYwZTllNzRlOTA4MjgwYmEyMGFkNGEzYjhkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SZWdlbnQgUGFyaywgSGFyYm91cmZyb250IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMwNWQ5MzVmMTZjMjQyMjdiYTQyYWE0N2Y3ZjVlZThiLnNldENvbnRlbnQoaHRtbF8zNTkxYTZmMGU5ZTc0ZTkwODI4MGJhMjBhZDRhM2I4ZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzU0ZmZkNGZhMzQ4NDBhMDlmODM3N2E0NzEzYjU4YjEuYmluZFBvcHVwKHBvcHVwXzMwNWQ5MzVmMTZjMjQyMjdiYTQyYWE0N2Y3ZjVlZThiKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMjU2MmMyOGI4NTc0OTdhOGNlYjViNTEwYzZmOTZkNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxODUxNzk5OTk5OTk5NiwgLTc5LjQ2NDc2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iMWEwMzZkYWE1YjY0ZDQwYWI0NWFmZmY3ZTVlOTZmYiA9ICQoYDxkaXYgaWQ9Imh0bWxfYjFhMDM2ZGFhNWI2NGQ0MGFiNDVhZmZmN2U1ZTk2ZmIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxhd3JlbmNlIE1hbm9yLCBMYXdyZW5jZSBIZWlnaHRzIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4LnNldENvbnRlbnQoaHRtbF9iMWEwMzZkYWE1YjY0ZDQwYWI0NWFmZmY3ZTVlOTZmYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzI1NjJjMjhiODU3NDk3YThjZWI1YjUxMGM2Zjk2ZDYuYmluZFBvcHVwKHBvcHVwXzhkNDRjNTA2NWEyMzRkMDJhMGIyZWNiNjMxMDI2NWI4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hNjUzNTNjMGEzYWY0NGUwYTNmZThhYjU0M2U4ZDBiMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjMwMTUsIC03OS4zODk0OTM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82MjlhMTM4MDQyZTI0MzgyODAyYzBhY2ZhOGZhZGY2OSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjI5YTEzODA0MmUyNDM4MjgwMmMwYWNmYThmYWRmNjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlF1ZWVuJiMzOTtzIFBhcmssIE9udGFyaW8gUHJvdmluY2lhbCBHb3Zlcm5tZW50IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4LnNldENvbnRlbnQoaHRtbF82MjlhMTM4MDQyZTI0MzgyODAyYzBhY2ZhOGZhZGY2OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTY1MzUzYzBhM2FmNDRlMGEzZmU4YWI1NDNlOGQwYjMuYmluZFBvcHVwKHBvcHVwXzg5MjRiM2I5MDI4YzQzMTFhMzdlYjVhYzk0ZjljMjc4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84ZjE3NTE5MzYyMzU0M2ZmOTdlNzI2NThkZjNhYTM3NiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwNjY4NjI5OTk5OTk5NiwgLTc5LjE5NDM1MzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kYzc3N2E1Mjg1YWM0ZjRjODg1NzFjYTM3YzA2NThiMSA9ICQoYDxkaXYgaWQ9Imh0bWxfZGM3NzdhNTI4NWFjNGY0Yzg4NTcxY2EzN2MwNjU4YjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1hbHZlcm4sIFJvdWdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3LnNldENvbnRlbnQoaHRtbF9kYzc3N2E1Mjg1YWM0ZjRjODg1NzFjYTM3YzA2NThiMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGYxNzUxOTM2MjM1NDNmZjk3ZTcyNjU4ZGYzYWEzNzYuYmluZFBvcHVwKHBvcHVwX2MxMDI1YWViNTdkYjQ0NGJiMDg2MzJlNDg4YmQwNGU3KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lNmM0ZDYxZDhjNDU0M2NiYjYyMDlkZGQwZWEwNWFiNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc0NTkwNTc5OTk5OTk5NiwgLTc5LjM1MjE4OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80MWFlMjI0ZmJkYzA0YjgxOGU5YTBhZWVmN2JmNmQyZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjNhZDNjMTQ3YTQwNDlkYTg0M2QzY2UwZTkyMmI0NzggPSAkKGA8ZGl2IGlkPSJodG1sX2YzYWQzYzE0N2E0MDQ5ZGE4NDNkM2NlMGU5MjJiNDc4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb24gTWlsbHMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDFhZTIyNGZiZGMwNGI4MThlOWEwYWVlZjdiZjZkMmQuc2V0Q29udGVudChodG1sX2YzYWQzYzE0N2E0MDQ5ZGE4NDNkM2NlMGU5MjJiNDc4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lNmM0ZDYxZDhjNDU0M2NiYjYyMDlkZGQwZWEwNWFiNy5iaW5kUG9wdXAocG9wdXBfNDFhZTIyNGZiZGMwNGI4MThlOWEwYWVlZjdiZjZkMmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q1OTRlNTA1ZmU2YTQ3YTY4MTU4ZWJhMjYyNGY5MmZkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA2Mzk3MiwgLTc5LjMwOTkzN10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9iYTRhNTYwOTc3Yjc0YmY5OWEyZDNlMTRjOTQ0MjFjYyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYmZmNWY5ZDUwYjYyNGVjNjlhZmNlNTIwNDdiMzFjNjUgPSAkKGA8ZGl2IGlkPSJodG1sX2JmZjVmOWQ1MGI2MjRlYzY5YWZjZTUyMDQ3YjMxYzY1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYXJrdmlldyBIaWxsLCBXb29kYmluZSBHYXJkZW5zIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2JhNGE1NjA5NzdiNzRiZjk5YTJkM2UxNGM5NDQyMWNjLnNldENvbnRlbnQoaHRtbF9iZmY1ZjlkNTBiNjI0ZWM2OWFmY2U1MjA0N2IzMWM2NSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDU5NGU1MDVmZTZhNDdhNjgxNThlYmEyNjI0ZjkyZmQuYmluZFBvcHVwKHBvcHVwX2JhNGE1NjA5NzdiNzRiZjk5YTJkM2UxNGM5NDQyMWNjKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80OTU0ZWJkNmFhNTI0ZTI3YjQxZDY2Mzk0YjJhYTIxOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1NzE2MTgsIC03OS4zNzg5MzcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85ZTIzZjZmNGU2YmU0OTY1OGMzNjBkZTAwNTAzNDcxOSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDliNjliYzdkMzZhNGEyMzhiMTFjYzE1NmY2YTIwY2EgPSAkKGA8ZGl2IGlkPSJodG1sXzQ5YjY5YmM3ZDM2YTRhMjM4YjExY2MxNTZmNmEyMGNhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5HYXJkZW4gRGlzdHJpY3QsIFJ5ZXJzb24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOWUyM2Y2ZjRlNmJlNDk2NThjMzYwZGUwMDUwMzQ3MTkuc2V0Q29udGVudChodG1sXzQ5YjY5YmM3ZDM2YTRhMjM4YjExY2MxNTZmNmEyMGNhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80OTU0ZWJkNmFhNTI0ZTI3YjQxZDY2Mzk0YjJhYTIxOC5iaW5kUG9wdXAocG9wdXBfOWUyM2Y2ZjRlNmJlNDk2NThjMzYwZGUwMDUwMzQ3MTkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzA4OTNhZTQzODUwMTQ1ZmQ4MjE3Zjk1YzQ0MzIzYWJkID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzA5NTc3LCAtNzkuNDQ1MDcyNTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNjRjMDI5OTRhZmY5NDU0MmE0NmY0NzFkMmFlMDRhYWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzA0OGZkNjVlZDEzMzRkOThhY2FkOTU5ODI0ODUyMTUzID0gJChgPGRpdiBpZD0iaHRtbF8wNDhmZDY1ZWQxMzM0ZDk4YWNhZDk1OTgyNDg1MjE1MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R2xlbmNhaXJuIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzY0YzAyOTk0YWZmOTQ1NDJhNDZmNDcxZDJhZTA0YWFmLnNldENvbnRlbnQoaHRtbF8wNDhmZDY1ZWQxMzM0ZDk4YWNhZDk1OTgyNDg1MjE1Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMDg5M2FlNDM4NTAxNDVmZDgyMTdmOTVjNDQzMjNhYmQuYmluZFBvcHVwKHBvcHVwXzY0YzAyOTk0YWZmOTQ1NDJhNDZmNDcxZDJhZTA0YWFmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80NmQ3MDZmN2ZlODg0OGFmYWE1MmY1OGUyNzJhYTc4MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MDk0MzIsIC03OS41NTQ3MjQ0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmYjM2MCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmZiMzYwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82YWRlNWY2YmEwZTk0NzZkODE3ODhiYjNmMzVhOGExMCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjcyNjZhOTc2NTk2NDhmMjhmMzM5NzNkZmQ0YTEyY2UgPSAkKGA8ZGl2IGlkPSJodG1sX2I3MjY2YTk3NjU5NjQ4ZjI4ZjMzOTczZGZkNGExMmNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0IERlYW5lIFBhcmssIFByaW5jZXNzIEdhcmRlbnMsIE1hcnRpbiBHcm92ZSwgSXNsaW5ndG9uLCBDbG92ZXJkYWxlIENsdXN0ZXIgNC4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzZhZGU1ZjZiYTBlOTQ3NmQ4MTc4OGJiM2YzNWE4YTEwLnNldENvbnRlbnQoaHRtbF9iNzI2NmE5NzY1OTY0OGYyOGYzMzk3M2RmZDRhMTJjZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNDZkNzA2ZjdmZTg4NDhhZmFhNTJmNThlMjcyYWE3ODEuYmluZFBvcHVwKHBvcHVwXzZhZGU1ZjZiYTBlOTQ3NmQ4MTc4OGJiM2YzNWE4YTEwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl82NjA5ZTQxMTQ1YmU0NDQ3ODNkYTNlYjUzNGZlZDAyNSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc4NDUzNTEsIC03OS4xNjA0OTcwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMWJiODAyYWMxMjYyNGM3OWJmMmViYmVkNGJiNDM3ODMgPSAkKGA8ZGl2IGlkPSJodG1sXzFiYjgwMmFjMTI2MjRjNzliZjJlYmJlZDRiYjQzNzgzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3VnZSBIaWxsLCBQb3J0IFVuaW9uLCBIaWdobGFuZCBDcmVlayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNS5zZXRDb250ZW50KGh0bWxfMWJiODAyYWMxMjYyNGM3OWJmMmViYmVkNGJiNDM3ODMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzY2MDllNDExNDViZTQ0NDc4M2RhM2ViNTM0ZmVkMDI1LmJpbmRQb3B1cChwb3B1cF83ZDhjMmUzYjI2M2Q0NmE3ODI2OWE1ZmY5NjZkMzJlNSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDQ2NGY0NzdlMTY0NDY0M2JlNWJmMzNkYmE3ZjQ1MTQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjU4OTk3MDAwMDAwMSwgLTc5LjM0MDkyM10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMjY4MDBjMjE4YTI0OWQ3YmNhZWQwMTc3OGU3OTI5NCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfOTAzNzk5ZmRjNmQyNGUwYzg5Y2E3Yzc2ODVkMjJiM2YgPSAkKGA8ZGl2IGlkPSJodG1sXzkwMzc5OWZkYzZkMjRlMGM4OWNhN2M3Njg1ZDIyYjNmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb24gTWlsbHMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzI2ODAwYzIxOGEyNDlkN2JjYWVkMDE3NzhlNzkyOTQuc2V0Q29udGVudChodG1sXzkwMzc5OWZkYzZkMjRlMGM4OWNhN2M3Njg1ZDIyYjNmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80NDY0ZjQ3N2UxNjQ0NjQzYmU1YmYzM2RiYTdmNDUxNC5iaW5kUG9wdXAocG9wdXBfMzI2ODAwYzIxOGEyNDlkN2JjYWVkMDE3NzhlNzkyOTQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2QwNDY1MDc1MWQwZjQwNjY5YjFkZTQwYjA5OGYyODI4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk1MzQzOTAwMDAwMDA1LCAtNzkuMzE4Mzg4N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lM2NjYTI4YjdjZTI0NjliOTM2ZDQzNDEzMGFlY2I5MSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYmQxMmVlYTEwZjFkNDg3YTljNDBmZGQ5ZjQ0NjAzMmQgPSAkKGA8ZGl2IGlkPSJodG1sX2JkMTJlZWExMGYxZDQ4N2E5YzQwZmRkOWY0NDYwMzJkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Xb29kYmluZSBIZWlnaHRzIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2UzY2NhMjhiN2NlMjQ2OWI5MzZkNDM0MTMwYWVjYjkxLnNldENvbnRlbnQoaHRtbF9iZDEyZWVhMTBmMWQ0ODdhOWM0MGZkZDlmNDQ2MDMyZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDA0NjUwNzUxZDBmNDA2NjliMWRlNDBiMDk4ZjI4MjguYmluZFBvcHVwKHBvcHVwX2UzY2NhMjhiN2NlMjQ2OWI5MzZkNDM0MTMwYWVjYjkxKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84NDFiMWMzZTgwNjI0MTU3OWU1OGNiYzlmNmZiMDQzOCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MTQ5MzksIC03OS4zNzU0MTc5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82MTgyYWI5MmY2Y2M0NzY2OWU1YmVhMDYxYjdjZGEyOSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjE4MmFiOTJmNmNjNDc2NjllNWJlYTA2MWI3Y2RhMjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0LiBKYW1lcyBUb3duIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4LnNldENvbnRlbnQoaHRtbF82MTgyYWI5MmY2Y2M0NzY2OWU1YmVhMDYxYjdjZGEyOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfODQxYjFjM2U4MDYyNDE1NzllNThjYmM5ZjZmYjA0MzguYmluZFBvcHVwKHBvcHVwXzUxMzJhM2I4NjczZDQwMjNhNzQ3MjE3MmVhZTE0YWY4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNWEwNDQ4NTk2ZTc0NzM1YmQwMjMxZTRkOTM0MGU2OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY5Mzc4MTMsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82NTc1NjhhMjkyMGM0NThmYWU4NGYxYjE2MTEyNTA3ZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjUyOGEyZGIwMjFjNDg2MWIxNTQzNzc2YjU1OTQ2NjAgPSAkKGA8ZGl2IGlkPSJodG1sXzY1MjhhMmRiMDIxYzQ4NjFiMTU0Mzc3NmI1NTk0NjYwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5IdW1ld29vZC1DZWRhcnZhbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjU3NTY4YTI5MjBjNDU4ZmFlODRmMWIxNjExMjUwN2Quc2V0Q29udGVudChodG1sXzY1MjhhMmRiMDIxYzQ4NjFiMTU0Mzc3NmI1NTk0NjYwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mNWEwNDQ4NTk2ZTc0NzM1YmQwMjMxZTRkOTM0MGU2OC5iaW5kUG9wdXAocG9wdXBfNjU3NTY4YTI5MjBjNDU4ZmFlODRmMWIxNjExMjUwN2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzE1NDIwNGQ3NGEzZDQ0OWM5Njk0ZjFkYWYxNWFjNzJmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQzNTE1MiwgLTc5LjU3NzIwMDc5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzBhNGY1NGZjMzQ3MTQ2NDM4YzcyYTJhMDFkM2I1MGI3ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8zOWZkMWRlNDJlY2M0NjQxOTZhOWZmMTFkOGM3MWE2ZiA9ICQoYDxkaXYgaWQ9Imh0bWxfMzlmZDFkZTQyZWNjNDY0MTk2YTlmZjExZDhjNzFhNmYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVyaW5nYXRlLCBCbG9vcmRhbGUgR2FyZGVucywgT2xkIEJ1cm5oYW10aG9ycGUsIE1hcmtsYW5kIFdvb2QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGE0ZjU0ZmMzNDcxNDY0MzhjNzJhMmEwMWQzYjUwYjcuc2V0Q29udGVudChodG1sXzM5ZmQxZGU0MmVjYzQ2NDE5NmE5ZmYxMWQ4YzcxYTZmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNTQyMDRkNzRhM2Q0NDljOTY5NGYxZGFmMTVhYzcyZi5iaW5kUG9wdXAocG9wdXBfMGE0ZjU0ZmMzNDcxNDY0MzhjNzJhMmEwMWQzYjUwYjcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzFiYmRjZjg1NzI0NDRjZGU5OWVjMzUxOTM4Y2UyMmQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzYzNTcyNiwgLTc5LjE4ODcxMTVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfY2MxMGU2NDE5ZjBhNGY1N2I2ZTI1MTQ4YzVkZmU5MjQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2VjYmJiMzQxMjYyODQ2OTQ4NGFhMTIwYTZlZjFhMTdiID0gJChgPGRpdiBpZD0iaHRtbF9lY2JiYjM0MTI2Mjg0Njk0ODRhYTEyMGE2ZWYxYTE3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+R3VpbGR3b29kLCBNb3JuaW5nc2lkZSwgV2VzdCBIaWxsIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2NjMTBlNjQxOWYwYTRmNTdiNmUyNTE0OGM1ZGZlOTI0LnNldENvbnRlbnQoaHRtbF9lY2JiYjM0MTI2Mjg0Njk0ODRhYTEyMGE2ZWYxYTE3Yik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMWJiZGNmODU3MjQ0NGNkZTk5ZWMzNTE5MzhjZTIyZDUuYmluZFBvcHVwKHBvcHVwX2NjMTBlNjQxOWYwYTRmNTdiNmUyNTE0OGM1ZGZlOTI0KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yMTE1NjMzNmNjOWY0NjY3OGMyMTlkYjZlMDY3YTg4MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3NjM1NzM5OTk5OTk5LCAtNzkuMjkzMDMxMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDE1ZmUwMjJiNmQzNDU0NjgzZDQwNWU2ZGYwYjE4NDEgPSAkKGA8ZGl2IGlkPSJodG1sX2QxNWZlMDIyYjZkMzQ1NDY4M2Q0MDVlNmRmMGIxODQxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgQmVhY2hlcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZC5zZXRDb250ZW50KGh0bWxfZDE1ZmUwMjJiNmQzNDU0NjgzZDQwNWU2ZGYwYjE4NDEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzIxMTU2MzM2Y2M5ZjQ2Njc4YzIxOWRiNmUwNjdhODgyLmJpbmRQb3B1cChwb3B1cF9lMGFiOTBiNDFjZDA0NmI5OTFiMjI1NzA0MjJjODg4ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMzFjMTE3YWQyMWI0NDQwZjgxNWNhNmZhYzkxMzMzYWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDQ3NzA3OTk5OTk5OTYsIC03OS4zNzMzMDY0XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mYzg0Yjg5ZGEyYjM0OWIxOGNhZDUwNGFiYjgzMDc3MiA9ICQoYDxkaXYgaWQ9Imh0bWxfZmM4NGI4OWRhMmIzNDliMThjYWQ1MDRhYmI4MzA3NzIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJlcmN6eSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzLnNldENvbnRlbnQoaHRtbF9mYzg0Yjg5ZGEyYjM0OWIxOGNhZDUwNGFiYjgzMDc3Mik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMzFjMTE3YWQyMWI0NDQwZjgxNWNhNmZhYzkxMzMzYWIuYmluZFBvcHVwKHBvcHVwXzc1ZWYxMWJjMTVhMjRhYzk4ZWYxZjI3MzAzN2MzZTQzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85ZDE5MGYzNDc2MzQ0ODZhYTQ0ZTQ2ODA0OTU5YTZkMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY4OTAyNTYsIC03OS40NTM1MTJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjZmZjU4OTc3OTA3NDZhYzk1ZWFhNDYzYjdjMzNmNmQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzA4Njg2ZGU2OWNmNjQwY2ViYTYwMzllNDRhOTQ2ZTZlID0gJChgPGRpdiBpZD0iaHRtbF8wODY4NmRlNjljZjY0MGNlYmE2MDM5ZTQ0YTk0NmU2ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FsZWRvbmlhLUZhaXJiYW5rcyBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9mNmZmNTg5Nzc5MDc0NmFjOTVlYWE0NjNiN2MzM2Y2ZC5zZXRDb250ZW50KGh0bWxfMDg2ODZkZTY5Y2Y2NDBjZWJhNjAzOWU0NGE5NDZlNmUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzlkMTkwZjM0NzYzNDQ4NmFhNDRlNDY4MDQ5NTlhNmQzLmJpbmRQb3B1cChwb3B1cF9mNmZmNTg5Nzc5MDc0NmFjOTVlYWE0NjNiN2MzM2Y2ZCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOGYzZGI5NDM3N2NiNGVhN2JlOWJhZDcyZWNkOGFkMmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzA5OTIxLCAtNzkuMjE2OTE3NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNTI5OGFlZGFjODZhNDg4YmJmNjYwNjFlYWIzMjdkMTMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU5NTQ3YjFhMjY0MjRlMzU5ODdhNTA5MDYwZTkwN2FjID0gJChgPGRpdiBpZD0iaHRtbF81OTU0N2IxYTI2NDI0ZTM1OTg3YTUwOTA2MGU5MDdhYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V29idXJuIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzUyOThhZWRhYzg2YTQ4OGJiZjY2MDYxZWFiMzI3ZDEzLnNldENvbnRlbnQoaHRtbF81OTU0N2IxYTI2NDI0ZTM1OTg3YTUwOTA2MGU5MDdhYyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGYzZGI5NDM3N2NiNGVhN2JlOWJhZDcyZWNkOGFkMmYuYmluZFBvcHVwKHBvcHVwXzUyOThhZWRhYzg2YTQ4OGJiZjY2MDYxZWFiMzI3ZDEzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl83NWExMTI4NGJkMjg0NzI4YjcyMmQ0NjAzMDJiNzcwNyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwOTA2MDQsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUzYzYwYmU0Y2FlNDQwMzE5ODg5Y2Q3NmY1MDJhM2M2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84MDg3NTNhNjMwMjE0MTI1YjJjYWYyOTdkNmJlZThjNCA9ICQoYDxkaXYgaWQ9Imh0bWxfODA4NzUzYTYzMDIxNDEyNWIyY2FmMjk3ZDZiZWU4YzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxlYXNpZGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTNjNjBiZTRjYWU0NDAzMTk4ODljZDc2ZjUwMmEzYzYuc2V0Q29udGVudChodG1sXzgwODc1M2E2MzAyMTQxMjViMmNhZjI5N2Q2YmVlOGM0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83NWExMTI4NGJkMjg0NzI4YjcyMmQ0NjAzMDJiNzcwNy5iaW5kUG9wdXAocG9wdXBfNTNjNjBiZTRjYWU0NDAzMTk4ODljZDc2ZjUwMmEzYzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBlMDg4ZjUyY2RhODQ0ZmNhNDQzY2Q1MWIzNzc1Zjg4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjU3OTUyNCwgLTc5LjM4NzM4MjZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfODQ5ZTM4ZDRlMTU1NDI4NWI5NzhiMWJiNThiNmVlM2YgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRhZTg3NWIwNWVmZjQ2ZDg4OTkxMDMwYjVmNDk1ZWQ2ID0gJChgPGRpdiBpZD0iaHRtbF80YWU4NzViMDVlZmY0NmQ4ODk5MTAzMGI1ZjQ5NWVkNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VudHJhbCBCYXkgU3RyZWV0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzg0OWUzOGQ0ZTE1NTQyODViOTc4YjFiYjU4YjZlZTNmLnNldENvbnRlbnQoaHRtbF80YWU4NzViMDVlZmY0NmQ4ODk5MTAzMGI1ZjQ5NWVkNik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMGUwODhmNTJjZGE4NDRmY2E0NDNjZDUxYjM3NzVmODguYmluZFBvcHVwKHBvcHVwXzg0OWUzOGQ0ZTE1NTQyODViOTc4YjFiYjU4YjZlZTNmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81MzQ5ZDRhZDNkNGQ0YjAyODAyNjA4Y2NiYWU3YjQ5YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2OTU0MiwgLTc5LjQyMjU2MzddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2UyZGRjYjE5YTYwODQ0OTViYTE3YTgyMWJjNThhZGQ3ID0gJChgPGRpdiBpZD0iaHRtbF9lMmRkY2IxOWE2MDg0NDk1YmExN2E4MjFiYzU4YWRkNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2hyaXN0aWUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIuc2V0Q29udGVudChodG1sX2UyZGRjYjE5YTYwODQ0OTViYTE3YTgyMWJjNThhZGQ3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81MzQ5ZDRhZDNkNGQ0YjAyODAyNjA4Y2NiYWU3YjQ5Yy5iaW5kUG9wdXAocG9wdXBfMGJjNDk5MDNmOGNjNGQ4NDg3ODE5ZGZmMGE4NTk2MjIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2EwNzFkNDdlOGRmYTQ2Yjc4YjM2NWMzNzdiZTFmM2M1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzczMTM2LCAtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTc1MzRkMzgzYjM1NGU5N2IwNGI4ZDQ5NzhmOWRhZDMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIwY2ZmYWRiYzQzOTQ5ZGViYTE2ZTJlNmQ5YjJmZDY5ID0gJChgPGRpdiBpZD0iaHRtbF8yMGNmZmFkYmM0Mzk0OWRlYmExNmUyZTZkOWIyZmQ2OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2VkYXJicmFlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2U3NTM0ZDM4M2IzNTRlOTdiMDRiOGQ0OTc4ZjlkYWQzLnNldENvbnRlbnQoaHRtbF8yMGNmZmFkYmM0Mzk0OWRlYmExNmUyZTZkOWIyZmQ2OSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTA3MWQ0N2U4ZGZhNDZiNzhiMzY1YzM3N2JlMWYzYzUuYmluZFBvcHVwKHBvcHVwX2U3NTM0ZDM4M2IzNTRlOTdiMDRiOGQ0OTc4ZjlkYWQzKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wZTUyNzZmZGJkNmM0YmZmYTBiMzU5YTc0MTM4YzFiMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgwMzc2MjIsIC03OS4zNjM0NTE3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81NjRlYjllYTM1YTY0N2ZiODUzODQzMWQzMzJkYjg1OCA9ICQoYDxkaXYgaWQ9Imh0bWxfNTY0ZWI5ZWEzNWE2NDdmYjg1Mzg0MzFkMzMyZGI4NTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkhpbGxjcmVzdCBWaWxsYWdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlLnNldENvbnRlbnQoaHRtbF81NjRlYjllYTM1YTY0N2ZiODUzODQzMWQzMzJkYjg1OCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMGU1Mjc2ZmRiZDZjNGJmZmEwYjM1OWE3NDEzOGMxYjEuYmluZFBvcHVwKHBvcHVwXzExNDdmNWE0ZmE3ZDQ2MmQ4ZTBlYTQ2YWU4NGIzNjFlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jNWFhZTZjZDdkOTI0OTAzOWQyZTRhODFiNjZlZTcyNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1NDMyODMsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ODFjNzRmZjI5MWI0MDgwYjZiODMzY2IzZmIwYzNhOCA9ICQoYDxkaXYgaWQ9Imh0bWxfOTgxYzc0ZmYyOTFiNDA4MGI2YjgzM2NiM2ZiMGMzYTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJhdGh1cnN0IE1hbm9yLCBXaWxzb24gSGVpZ2h0cywgRG93bnN2aWV3IE5vcnRoIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlLnNldENvbnRlbnQoaHRtbF85ODFjNzRmZjI5MWI0MDgwYjZiODMzY2IzZmIwYzNhOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYzVhYWU2Y2Q3ZDkyNDkwMzlkMmU0YTgxYjY2ZWU3MjYuYmluZFBvcHVwKHBvcHVwXzM4MGQ4ZGEyNTgxODQ0ODk4OTg0NTc3MDRlNzM2YmVlKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMTY3YWE5YWZjNTQ0Mjc0OGE5YWE5ZTcxZGNmOWQ4MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNTM2ODksIC03OS4zNDkzNzE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82ZTUxZTBkMWZiNTA0ZDM0YTA0NzAyMzMzNzU1YzRjNSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZDVhM2YyODM4OTM3NDk4NWJlZjNkMWU5NTM5ZGI1NWMgPSAkKGA8ZGl2IGlkPSJodG1sX2Q1YTNmMjgzODkzNzQ5ODViZWYzZDFlOTUzOWRiNTVjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaG9ybmNsaWZmZSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzZlNTFlMGQxZmI1MDRkMzRhMDQ3MDIzMzM3NTVjNGM1LnNldENvbnRlbnQoaHRtbF9kNWEzZjI4Mzg5Mzc0OTg1YmVmM2QxZTk1MzlkYjU1Yyk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYjE2N2FhOWFmYzU0NDI3NDhhOWFhOWU3MWRjZjlkODMuYmluZFBvcHVwKHBvcHVwXzZlNTFlMGQxZmI1MDRkMzRhMDQ3MDIzMzM3NTVjNGM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wODllZTFiYzY4NmY0MTI1YjcyZjQ1MTU0MmZkNDJhYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MDU3MTIwMDAwMDAxLCAtNzkuMzg0NTY3NV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82ODMxZjg3NzZiMWU0NmQ4YjZjN2JiOGMyZmUxNTUyZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZjk5MGNkNWYyMzg4NGE3NzhhYWJiOTQ4ODYxODRhNDAgPSAkKGA8ZGl2IGlkPSJodG1sX2Y5OTBjZDVmMjM4ODRhNzc4YWFiYjk0ODg2MTg0YTQwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SaWNobW9uZCwgQWRlbGFpZGUsIEtpbmcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjgzMWY4Nzc2YjFlNDZkOGI2YzdiYjhjMmZlMTU1MmQuc2V0Q29udGVudChodG1sX2Y5OTBjZDVmMjM4ODRhNzc4YWFiYjk0ODg2MTg0YTQwKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wODllZTFiYzY4NmY0MTI1YjcyZjQ1MTU0MmZkNDJhYi5iaW5kUG9wdXAocG9wdXBfNjgzMWY4Nzc2YjFlNDZkOGI2YzdiYjhjMmZlMTU1MmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzY2OGYxNDY3ZDRjNzRkN2M4MmYxMGM1YmYwZTdjM2QyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY5MDA1MTAwMDAwMDEsIC03OS40NDIyNTkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2IxOWQ0Mzk0ZmIyZTRjOWQ5MzhjNGI5MTMzNjcxMWEyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF80MWNhZDZhOTc2ZjA0MWRlOTlmYzg5OTA0ZjVhYjJhZiA9ICQoYDxkaXYgaWQ9Imh0bWxfNDFjYWQ2YTk3NmYwNDFkZTk5ZmM4OTkwNGY1YWIyYWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkR1ZmZlcmluLCBEb3ZlcmNvdXJ0IFZpbGxhZ2UgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYjE5ZDQzOTRmYjJlNGM5ZDkzOGM0YjkxMzM2NzExYTIuc2V0Q29udGVudChodG1sXzQxY2FkNmE5NzZmMDQxZGU5OWZjODk5MDRmNWFiMmFmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82NjhmMTQ2N2Q0Yzc0ZDdjODJmMTBjNWJmMGU3YzNkMi5iaW5kUG9wdXAocG9wdXBfYjE5ZDQzOTRmYjJlNGM5ZDkzOGM0YjkxMzM2NzExYTIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzlmOGI0Yzk2NmJlNTRiOWI5NTgyMzI2MjMxOTM1YzEyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzQ0NzM0MiwgLTc5LjIzOTQ3NjA5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjMDBiNWViIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMwMGI1ZWIiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzgxODRkZTliZWYxNjRmNmViNmI1YTRmOGM0NzllZDk4ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82YWFjZTM0ZmVkMTA0N2ZmOTU0ODFiNzExZDhiNDE2YSA9ICQoYDxkaXYgaWQ9Imh0bWxfNmFhY2UzNGZlZDEwNDdmZjk1NDgxYjcxMWQ4YjQxNmEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlNjYXJib3JvdWdoIFZpbGxhZ2UgQ2x1c3RlciAyLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfODE4NGRlOWJlZjE2NGY2ZWI2YjVhNGY4YzQ3OWVkOTguc2V0Q29udGVudChodG1sXzZhYWNlMzRmZWQxMDQ3ZmY5NTQ4MWI3MTFkOGI0MTZhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZjhiNGM5NjZiZTU0YjliOTU4MjMyNjIzMTkzNWMxMi5iaW5kUG9wdXAocG9wdXBfODE4NGRlOWJlZjE2NGY2ZWI2YjVhNGY4YzQ3OWVkOTgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y0YjM2YWJkZGU2ODQ5MjVhMjZjZWU3M2NjYzRlZTBhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzc4NTE3NSwgLTc5LjM0NjU1NTddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjFhNjI0ZDc5M2UxNDRjMThjOTFhN2FlNWEwNjRmN2UgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVkNTc0YmU1MzRiNTQwNTZhYjk4MDdhODkwZGYzYjQwID0gJChgPGRpdiBpZD0iaHRtbF81ZDU3NGJlNTM0YjU0MDU2YWI5ODA3YTg5MGRmM2I0MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RmFpcnZpZXcsIEhlbnJ5IEZhcm0sIE9yaW9sZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9mMWE2MjRkNzkzZTE0NGMxOGM5MWE3YWU1YTA2NGY3ZS5zZXRDb250ZW50KGh0bWxfNWQ1NzRiZTUzNGI1NDA1NmFiOTgwN2E4OTBkZjNiNDApOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Y0YjM2YWJkZGU2ODQ5MjVhMjZjZWU3M2NjYzRlZTBhLmJpbmRQb3B1cChwb3B1cF9mMWE2MjRkNzkzZTE0NGMxOGM5MWE3YWU1YTA2NGY3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmJkMjhiZGJjODg5NDY0MTk4NzQ5OWQ5YmU1MDM4NzQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Njc5ODAzLCAtNzkuNDg3MjYxOTAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMmMzMTM1NjdkNTk3NGVhMThlOGI3NzI1YTQ5ODhhNGIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg5NzBmYTRlYTUxZDRlOGJhOWU3NzExZGY5YWM3YmIxID0gJChgPGRpdiBpZD0iaHRtbF84OTcwZmE0ZWE1MWQ0ZThiYTllNzcxMWRmOWFjN2JiMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3b29kIFBhcmssIFlvcmsgVW5pdmVyc2l0eSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yYzMxMzU2N2Q1OTc0ZWExOGU4Yjc3MjVhNDk4OGE0Yi5zZXRDb250ZW50KGh0bWxfODk3MGZhNGVhNTFkNGU4YmE5ZTc3MTFkZjlhYzdiYjEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2ZiZDI4YmRiYzg4OTQ2NDE5ODc0OTlkOWJlNTAzODc0LmJpbmRQb3B1cChwb3B1cF8yYzMxMzU2N2Q1OTc0ZWExOGU4Yjc3MjVhNDk4OGE0YikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzk5YTJhYjI0YmMyNDk2MWIyNmEyNDNiNjZhZDZjNmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODUzNDcsIC03OS4zMzgxMDY1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjZmYwMDAwIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiNmZjAwMDAiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzkzY2IwMTA4Zjc5MDRlYzc4YWYxZjU3MTg2YjhiNjNjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wYzEwYTlkZjcwZDk0ZjA3OGQzYTkxNDNkZTgxNmEyMiA9ICQoYDxkaXYgaWQ9Imh0bWxfMGMxMGE5ZGY3MGQ5NGYwNzhkM2E5MTQzZGU4MTZhMjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVhc3QgVG9yb250bywgQnJvYWR2aWV3IE5vcnRoIChPbGQgRWFzdCBZb3JrKSBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85M2NiMDEwOGY3OTA0ZWM3OGFmMWY1NzE4NmI4YjYzYy5zZXRDb250ZW50KGh0bWxfMGMxMGE5ZGY3MGQ5NGYwNzhkM2E5MTQzZGU4MTZhMjIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2M5OWEyYWIyNGJjMjQ5NjFiMjZhMjQzYjY2YWQ2YzZkLmJpbmRQb3B1cChwb3B1cF85M2NiMDEwOGY3OTA0ZWM3OGFmMWY1NzE4NmI4YjYzYykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTk5YWE1OWQ1YTNhNDM3ZDk4YWMyZjhhNTA5OTg2MDkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDA4MTU3LCAtNzkuMzgxNzUyMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMWMwYWEzYTZkODY4NGY5Yzg5YTUxYmU3MTcxMDk2ODUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzYyMjg4MjYxYmI5MTQwNjg5NDk1M2NjOGU2ZGNjOWY0ID0gJChgPGRpdiBpZD0iaHRtbF82MjI4ODI2MWJiOTE0MDY4OTQ5NTNjYzhlNmRjYzlmNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGFyYm91cmZyb250IEVhc3QsIFVuaW9uIFN0YXRpb24sIFRvcm9udG8gSXNsYW5kcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xYzBhYTNhNmQ4Njg0ZjljODlhNTFiZTcxNzEwOTY4NS5zZXRDb250ZW50KGh0bWxfNjIyODgyNjFiYjkxNDA2ODk0OTUzY2M4ZTZkY2M5ZjQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzk5OWFhNTlkNWEzYTQzN2Q5OGFjMmY4YTUwOTk4NjA5LmJpbmRQb3B1cChwb3B1cF8xYzBhYTNhNmQ4Njg0ZjljODlhNTFiZTcxNzEwOTY4NSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjg4OGJkMDc1ODdlNGM4M2JjNTUzYzU3NjgwZThlMTUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDc5MjY3MDAwMDAwMDYsIC03OS40MTk3NDk3XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzVmYzgyN2U4MTQwZjQzZjA4ZGJkZDFmMjkxNjA0N2VlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xYTEzNjM2ZThjZTE0Y2M2YmM0MTg5OWJiYTAzNDU5NSA9ICQoYDxkaXYgaWQ9Imh0bWxfMWExMzYzNmU4Y2UxNGNjNmJjNDE4OTliYmEwMzQ1OTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxpdHRsZSBQb3J0dWdhbCwgVHJpbml0eSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF81ZmM4MjdlODE0MGY0M2YwOGRiZGQxZjI5MTYwNDdlZS5zZXRDb250ZW50KGh0bWxfMWExMzYzNmU4Y2UxNGNjNmJjNDE4OTliYmEwMzQ1OTUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI4ODhiZDA3NTg3ZTRjODNiYzU1M2M1NzY4MGU4ZTE1LmJpbmRQb3B1cChwb3B1cF81ZmM4MjdlODE0MGY0M2YwOGRiZGQxZjI5MTYwNDdlZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjc1NWQ0ZWQwMjk0NGI2N2JjNGYzYzEzYTRiYTViNzUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mjc5MjkyLCAtNzkuMjYyMDI5NDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDk5Yjk0MWZlY2YxNDdiMGE0MDNlNDcwZjQxZGJjOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzE2Y2RiZDU3ZGFiYzQwYzZhNzY3NzVmNjg0Y2Q5MWQxID0gJChgPGRpdiBpZD0iaHRtbF8xNmNkYmQ1N2RhYmM0MGM2YTc2Nzc1ZjY4NGNkOTFkMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2VubmVkeSBQYXJrLCBJb252aWV3LCBFYXN0IEJpcmNobW91bnQgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kOTliOTQxZmVjZjE0N2IwYTQwM2U0NzBmNDFkYmM5Zi5zZXRDb250ZW50KGh0bWxfMTZjZGJkNTdkYWJjNDBjNmE3Njc3NWY2ODRjZDkxZDEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I3NTVkNGVkMDI5NDRiNjdiYzRmM2MxM2E0YmE1Yjc1LmJpbmRQb3B1cChwb3B1cF9kOTliOTQxZmVjZjE0N2IwYTQwM2U0NzBmNDFkYmM5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODBhYmFmMDk3M2ZiNGQzNmJkYjQ5YWY0OTg3N2Y5MmYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43ODY5NDczLCAtNzkuMzg1OTc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2FiMGFhYWMwNTRiYTQ3N2ViMTQ2YmU0MmZmYjllN2Y0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ZDI2Y2Q2MzUyMTM0YzJjOWRjZGQ1Mjk4NDdjZWE2YyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWQyNmNkNjM1MjEzNGMyYzlkY2RkNTI5ODQ3Y2VhNmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJheXZpZXcgVmlsbGFnZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9hYjBhYWFjMDU0YmE0NzdlYjE0NmJlNDJmZmI5ZTdmNC5zZXRDb250ZW50KGh0bWxfOWQyNmNkNjM1MjEzNGMyYzlkY2RkNTI5ODQ3Y2VhNmMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzgwYWJhZjA5NzNmYjRkMzZiZGI0OWFmNDk4NzdmOTJmLmJpbmRQb3B1cChwb3B1cF9hYjBhYWFjMDU0YmE0NzdlYjE0NmJlNDJmZmI5ZTdmNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzQ3ZGY3M2RiMWFmNDBjM2EwYTFhOTRiY2FlMzA0MGUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43Mzc0NzMyMDAwMDAwMDQsIC03OS40NjQ3NjMyOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9kZmVhYTliNDZmOTU0N2E5YjJiNzQ0Mzc3YTc2YTBjNyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjhkODg4NTcxZGRlNGQ2Yjg3ZTg1YWVlNzM1ZGFiYWQgPSAkKGA8ZGl2IGlkPSJodG1sX2I4ZDg4ODU3MWRkZTRkNmI4N2U4NWFlZTczNWRhYmFkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZGZlYWE5YjQ2Zjk1NDdhOWIyYjc0NDM3N2E3NmEwYzcuc2V0Q29udGVudChodG1sX2I4ZDg4ODU3MWRkZTRkNmI4N2U4NWFlZTczNWRhYmFkKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jNDdkZjczZGIxYWY0MGMzYTBhMWE5NGJjYWUzMDQwZS5iaW5kUG9wdXAocG9wdXBfZGZlYWE5YjQ2Zjk1NDdhOWIyYjc0NDM3N2E3NmEwYzcpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q2OGQwYzQ2ZjgxYzQ0NDBiNjE1MWUzZjhiZTBiMjgwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjc5NTU3MSwgLTc5LjM1MjE4OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80NmI2Y2FjN2EyNGU0YTlmYmY2NjdlOWVmMmU5NDAwYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNjU1OWZkMTUwZTliNDMzM2EwZTg3ZjQ2ZWZkMGIxMGYgPSAkKGA8ZGl2IGlkPSJodG1sXzY1NTlmZDE1MGU5YjQzMzNhMGU4N2Y0NmVmZDBiMTBmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgRGFuZm9ydGggV2VzdCwgUml2ZXJkYWxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzQ2YjZjYWM3YTI0ZTRhOWZiZjY2N2U5ZWYyZTk0MDBhLnNldENvbnRlbnQoaHRtbF82NTU5ZmQxNTBlOWI0MzMzYTBlODdmNDZlZmQwYjEwZik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDY4ZDBjNDZmODFjNDQ0MGI2MTUxZTNmOGJlMGIyODAuYmluZFBvcHVwKHBvcHVwXzQ2YjZjYWM3YTI0ZTRhOWZiZjY2N2U5ZWYyZTk0MDBhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hMjhlODA4YTU5NDA0NzhlYmFlZTNjOTBkNWI2MjkxMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0NzE3NjgsIC03OS4zODE1NzY0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9kZDExM2I4Yzk1ZjU0NWE4OGExZmMzYTBlMTc2NGU4ZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYTQ1Zjc2YmIzNTVhNDg3OGFhY2U2MDBlYTBkN2IwMmIgPSAkKGA8ZGl2IGlkPSJodG1sX2E0NWY3NmJiMzU1YTQ4NzhhYWNlNjAwZWEwZDdiMDJiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ub3JvbnRvIERvbWluaW9uIENlbnRyZSwgRGVzaWduIEV4Y2hhbmdlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2RkMTEzYjhjOTVmNTQ1YTg4YTFmYzNhMGUxNzY0ZThmLnNldENvbnRlbnQoaHRtbF9hNDVmNzZiYjM1NWE0ODc4YWFjZTYwMGVhMGQ3YjAyYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTI4ZTgwOGE1OTQwNDc4ZWJhZWUzYzkwZDViNjI5MTMuYmluZFBvcHVwKHBvcHVwX2RkMTEzYjhjOTVmNTQ1YTg4YTFmYzNhMGUxNzY0ZThmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9jM2ZjYjM5NmYzNjA0YjkzYTdjNGQ1ZWZmYmRhYjM4OCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjg0NzIsIC03OS40MjgxOTE0MDAwMDAwMl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMDE3NDUzZTcxYWQzNGRkNjg1MjRlZDlmZmI3MmY2MTYgPSAkKGA8ZGl2IGlkPSJodG1sXzAxNzQ1M2U3MWFkMzRkZDY4NTI0ZWQ5ZmZiNzJmNjE2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ccm9ja3RvbiwgUGFya2RhbGUgVmlsbGFnZSwgRXhoaWJpdGlvbiBQbGFjZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNy5zZXRDb250ZW50KGh0bWxfMDE3NDUzZTcxYWQzNGRkNjg1MjRlZDlmZmI3MmY2MTYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2MzZmNiMzk2ZjM2MDRiOTNhN2M0ZDVlZmZiZGFiMzg4LmJpbmRQb3B1cChwb3B1cF83ZjU1OWI2MjJhM2I0N2ZhODI4MDI0YjU3OTg4YzJjNykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNmEyY2EwMzg2NjFhNGRiZDk5MTYzZDhmZDUxZWFkZjYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTExMTE3MDAwMDAwMDQsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzkxYTI3YzI2YzM0ODQyNDc4MjUzOTI1ZTYwNzA0ZjNhID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iZjNlODZjOTQzNWQ0OTQ1YjY2ZjQ3NGIwMzc4NmI0YSA9ICQoYDxkaXYgaWQ9Imh0bWxfYmYzZTg2Yzk0MzVkNDk0NWI2NmY0NzRiMDM3ODZiNGEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkdvbGRlbiBNaWxlLCBDbGFpcmxlYSwgT2FrcmlkZ2UgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOTFhMjdjMjZjMzQ4NDI0NzgyNTM5MjVlNjA3MDRmM2Euc2V0Q29udGVudChodG1sX2JmM2U4NmM5NDM1ZDQ5NDViNjZmNDc0YjAzNzg2YjRhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82YTJjYTAzODY2MWE0ZGJkOTkxNjNkOGZkNTFlYWRmNi5iaW5kUG9wdXAocG9wdXBfOTFhMjdjMjZjMzQ4NDI0NzgyNTM5MjVlNjA3MDRmM2EpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzIwYTc4MThiYmM5ZTQxNTRhNTk2YmJkM2M5OWM4ODQ1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5MDE0NiwgLTc5LjUwNjk0MzZdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMGUxNDRjOGE4NjBjNDNjYjhkNjg3MjcyODc4NDQ2NzYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI1NTFlOGE2YTZlZjQ5M2RhMjRjN2E4OWU4NGNlYzQ4ID0gJChgPGRpdiBpZD0iaHRtbF8yNTUxZThhNmE2ZWY0OTNkYTI0YzdhODllODRjZWM0OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+RG93bnN2aWV3IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzBlMTQ0YzhhODYwYzQzY2I4ZDY4NzI3Mjg3ODQ0Njc2LnNldENvbnRlbnQoaHRtbF8yNTUxZThhNmE2ZWY0OTNkYTI0YzdhODllODRjZWM0OCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjBhNzgxOGJiYzllNDE1NGE1OTZiYmQzYzk5Yzg4NDUuYmluZFBvcHVwKHBvcHVwXzBlMTQ0YzhhODYwYzQzY2I4ZDY4NzI3Mjg3ODQ0Njc2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zNmZhZmM5OTZiNDM0YzA1YTEzMGQ4MDc3Njg3NjkwZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2ODk5ODUsIC03OS4zMTU1NzE1OTk5OTk5OF0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZGQxYzkwNjExYmE0ODZlYWRlYjQyM2NjYTcyNWViMyA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjkyMmFjMTFmZDg0NGJkNGFkZDI3ZjhlNDFhY2ExOWMgPSAkKGA8ZGl2IGlkPSJodG1sX2I5MjJhYzExZmQ4NDRiZDRhZGQyN2Y4ZTQxYWNhMTljIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5JbmRpYSBCYXphYXIsIFRoZSBCZWFjaGVzIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMmRkMWM5MDYxMWJhNDg2ZWFkZWI0MjNjY2E3MjVlYjMuc2V0Q29udGVudChodG1sX2I5MjJhYzExZmQ4NDRiZDRhZGQyN2Y4ZTQxYWNhMTljKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8zNmZhZmM5OTZiNDM0YzA1YTEzMGQ4MDc3Njg3NjkwZC5iaW5kUG9wdXAocG9wdXBfMmRkMWM5MDYxMWJhNDg2ZWFkZWI0MjNjY2E3MjVlYjMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RmZTU4ZDVkOGNmYjQxMTY5MThlMTZkMTU5MTNiZDU0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4MTk4NSwgLTc5LjM3OTgxNjkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzk1NDc2ZmRkZWM1NTQ5Zjg4N2FiZDIyN2I0Mzg3NzkwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF85ZGMzZWE3NjY5MTI0ZTQ3OWI2ZGEwNGNjOWJkZTM0MyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWRjM2VhNzY2OTEyNGU0NzliNmRhMDRjYzliZGUzNDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNvbW1lcmNlIENvdXJ0LCBWaWN0b3JpYSBIb3RlbCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NTQ3NmZkZGVjNTU0OWY4ODdhYmQyMjdiNDM4Nzc5MC5zZXRDb250ZW50KGh0bWxfOWRjM2VhNzY2OTEyNGU0NzliNmRhMDRjYzliZGUzNDMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2RmZTU4ZDVkOGNmYjQxMTY5MThlMTZkMTU5MTNiZDU0LmJpbmRQb3B1cChwb3B1cF85NTQ3NmZkZGVjNTU0OWY4ODdhYmQyMjdiNDM4Nzc5MCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjJiODA1NTlmYTk4NGZhZDg5ZDlmYjkzNjIzYTQ2NjggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTM3NTYyMDAwMDAwMDYsIC03OS40OTAwNzM4XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzQyMzIwZjNjNjA3MzRmNGZhN2MzYjdkNjhmODY5MDBlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF83ZDZiMmI3ZjA0YzU0NzFhYTFjMzU0NjQ0OTI1ZmI5MiA9ICQoYDxkaXYgaWQ9Imh0bWxfN2Q2YjJiN2YwNGM1NDcxYWExYzM1NDY0NDkyNWZiOTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk5vcnRoIFBhcmssIE1hcGxlIExlYWYgUGFyaywgVXB3b29kIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDIzMjBmM2M2MDczNGY0ZmE3YzNiN2Q2OGY4NjkwMGUuc2V0Q29udGVudChodG1sXzdkNmIyYjdmMDRjNTQ3MWFhMWMzNTQ2NDQ5MjVmYjkyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMmI4MDU1OWZhOTg0ZmFkODlkOWZiOTM2MjNhNDY2OC5iaW5kUG9wdXAocG9wdXBfNDIzMjBmM2M2MDczNGY0ZmE3YzNiN2Q2OGY4NjkwMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYzYTgxZWVlYTU5MDRjYTA4ZmMyNzUxZjE1ZGRhYTFiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU2MzAzMywgLTc5LjU2NTk2MzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjMDBiNWViIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiMwMGI1ZWIiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzdmOTM4YjVlZTNlZDRlNWY5MWE0YTIzZDJjYWJmMjM2ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF82NDUyMjUxZDJhNzg0OWZkOGE0ZTdhYjRiOTA5M2NjZSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjQ1MjI1MWQyYTc4NDlmZDhhNGU3YWI0YjkwOTNjY2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkh1bWJlciBTdW1taXQgQ2x1c3RlciAyLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfN2Y5MzhiNWVlM2VkNGU1ZjkxYTRhMjNkMmNhYmYyMzYuc2V0Q29udGVudChodG1sXzY0NTIyNTFkMmE3ODQ5ZmQ4YTRlN2FiNGI5MDkzY2NlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82M2E4MWVlZWE1OTA0Y2EwOGZjMjc1MWYxNWRkYWExYi5iaW5kUG9wdXAocG9wdXBfN2Y5MzhiNWVlM2VkNGU1ZjkxYTRhMjNkMmNhYmYyMzYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzRmNGE2YjJhYjY3MzQ0YWE4YzA4ZDFjMGEyMTllMGY1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzE2MzE2LCAtNzkuMjM5NDc2MDk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzQwYWM5YzM4Y2VkYTRmZmRiYTg4YTRiMmFhNDE0ZjYzID0gJChgPGRpdiBpZD0iaHRtbF80MGFjOWMzOGNlZGE0ZmZkYmE4OGE0YjJhYTQxNGY2MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xpZmZzaWRlLCBDbGlmZmNyZXN0LCBTY2FyYm9yb3VnaCBWaWxsYWdlIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEuc2V0Q29udGVudChodG1sXzQwYWM5YzM4Y2VkYTRmZmRiYTg4YTRiMmFhNDE0ZjYzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl80ZjRhNmIyYWI2NzM0NGFhOGMwOGQxYzBhMjE5ZTBmNS5iaW5kUG9wdXAocG9wdXBfMzE1ZmExNDNmNmQ0NDM1Yzg4MWZjMjk4OGFjYTc4YzEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdiMmExNzQ3OTk2YjRlMThiMTUwOTI0MmNhM2JlNzU1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzg5MDUzLCAtNzkuNDA4NDkyNzk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2YyMGMxMDg2YzJiODRmZmI4ZmE1MDRlNWZlNTU4MjNiID0gJChgPGRpdiBpZD0iaHRtbF9mMjBjMTA4NmMyYjg0ZmZiOGZhNTA0ZTVmZTU1ODIzYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgTmV3dG9uYnJvb2sgQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYuc2V0Q29udGVudChodG1sX2YyMGMxMDg2YzJiODRmZmI4ZmE1MDRlNWZlNTU4MjNiKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl83YjJhMTc0Nzk5NmI0ZTE4YjE1MDkyNDJjYTNiZTc1NS5iaW5kUG9wdXAocG9wdXBfZTQ3ZTQwODM5ZjVjNDUyZmE1ZWU3YmY1ZDk5ZDMxOTYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2ZjZmYyZGUwNjkwNzQzMGQ5NDMwNTdlNGJjOWY5Yzk1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4NDk2NCwgLTc5LjQ5NTY5NzQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzc0OTQ2NGNkOWRhODQ3ZWFiMTMxZTYyNmQ1Y2M1ZjlmID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xZGIwYjEzYmFmMWI0MjAxYTcyMTcwNGRhMmY1YTY5NyA9ICQoYDxkaXYgaWQ9Imh0bWxfMWRiMGIxM2JhZjFiNDIwMWE3MjE3MDRkYTJmNWE2OTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvd25zdmlldyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83NDk0NjRjZDlkYTg0N2VhYjEzMWU2MjZkNWNjNWY5Zi5zZXRDb250ZW50KGh0bWxfMWRiMGIxM2JhZjFiNDIwMWE3MjE3MDRkYTJmNWE2OTcpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2ZjZmYyZGUwNjkwNzQzMGQ5NDMwNTdlNGJjOWY5Yzk1LmJpbmRQb3B1cChwb3B1cF83NDk0NjRjZDlkYTg0N2VhYjEzMWU2MjZkNWNjNWY5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYjcyNTg0Mjc0NjljNGE1OGIxYTdhY2MyZmRjZDdhMWYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTk1MjU1LCAtNzkuMzQwOTIzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzA1ZDIzODIwMjI2NDRlZjNhZTgyYzQyMjlhNGRmODA5ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9jMWE0MjRkNDgwZjA0ZTljYThhYWQyZWVjY2IyYTA0YyA9ICQoYDxkaXYgaWQ9Imh0bWxfYzFhNDI0ZDQ4MGYwNGU5Y2E4YWFkMmVlY2NiMmEwNGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlN0dWRpbyBEaXN0cmljdCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8wNWQyMzgyMDIyNjQ0ZWYzYWU4MmM0MjI5YTRkZjgwOS5zZXRDb250ZW50KGh0bWxfYzFhNDI0ZDQ4MGYwNGU5Y2E4YWFkMmVlY2NiMmEwNGMpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I3MjU4NDI3NDY5YzRhNThiMWE3YWNjMmZkY2Q3YTFmLmJpbmRQb3B1cChwb3B1cF8wNWQyMzgyMDIyNjQ0ZWYzYWU4MmM0MjI5YTRkZjgwOSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYzIxODEyOGYwMDAxNGJlMTliODQwM2E4MDI0ZjlkMjIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MzMyODI1LCAtNzkuNDE5NzQ5N10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zMWMxMmM1NzhmZmI0OTE5YTk3ZWEyMGFjNzAzM2MwZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfMzZkYmJlZWEyMDRmNDE3OThhOTY0MWMwY2E4MzUyNTYgPSAkKGA8ZGl2IGlkPSJodG1sXzM2ZGJiZWVhMjA0ZjQxNzk4YTk2NDFjMGNhODM1MjU2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CZWRmb3JkIFBhcmssIExhd3JlbmNlIE1hbm9yIEVhc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMzFjMTJjNTc4ZmZiNDkxOWE5N2VhMjBhYzcwMzNjMGUuc2V0Q29udGVudChodG1sXzM2ZGJiZWVhMjA0ZjQxNzk4YTk2NDFjMGNhODM1MjU2KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jMjE4MTI4ZjAwMDE0YmUxOWI4NDAzYTgwMjRmOWQyMi5iaW5kUG9wdXAocG9wdXBfMzFjMTJjNTc4ZmZiNDkxOWE5N2VhMjBhYzcwMzNjMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBkNzA1YWZjN2Y2MjRiYmY4MWIyYzUyNzlmMDBkOWQ4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjkxMTE1OCwgLTc5LjQ3NjAxMzI5OTk5OTk5XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzEyZjRhN2RmNTI0ZTRlY2Y5NTBiZGE0NmI5ZmJkZGUzID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YjdlNGEyZGM3Yzk0YzM3YjFjNTMxYmJiODcxODU3NiA9ICQoYDxkaXYgaWQ9Imh0bWxfNWI3ZTRhMmRjN2M5NGMzN2IxYzUzMWJiYjg3MTg1NzYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRlbCBSYXksIE1vdW50IERlbm5pcywgS2VlbHNkYWxlIGFuZCBTaWx2ZXJ0aG9ybiBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8xMmY0YTdkZjUyNGU0ZWNmOTUwYmRhNDZiOWZiZGRlMy5zZXRDb250ZW50KGh0bWxfNWI3ZTRhMmRjN2M5NGMzN2IxYzUzMWJiYjg3MTg1NzYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzBkNzA1YWZjN2Y2MjRiYmY4MWIyYzUyNzlmMDBkOWQ4LmJpbmRQb3B1cChwb3B1cF8xMmY0YTdkZjUyNGU0ZWNmOTUwYmRhNDZiOWZiZGRlMykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDRmMDkxNTQzNzk0NDYyMmIwNThkYmEyM2UyYWU1ZmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MjQ3NjU5LCAtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MGZmYjQiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwZmZiNCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfN2RlNmFkMzQ1ZjUzNGZkM2FmMDYxNmYwNjhiNGVlMjYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzQ4OTY5YzBiMmVlODRlYjZiZWMyMGVjMjVjM2JjMWRiID0gJChgPGRpdiBpZD0iaHRtbF80ODk2OWMwYjJlZTg0ZWI2YmVjMjBlYzI1YzNiYzFkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SHVtYmVybGVhLCBFbWVyeSBDbHVzdGVyIDMuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83ZGU2YWQzNDVmNTM0ZmQzYWYwNjE2ZjA2OGI0ZWUyNi5zZXRDb250ZW50KGh0bWxfNDg5NjljMGIyZWU4NGViNmJlYzIwZWMyNWMzYmMxZGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q0ZjA5MTU0Mzc5NDQ2MjJiMDU4ZGJhMjNlMmFlNWZkLmJpbmRQb3B1cChwb3B1cF83ZGU2YWQzNDVmNTM0ZmQzYWYwNjE2ZjA2OGI0ZWUyNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYTJmYTRlOTEzMWFmNGJhOGFmOWI2NjNmODk5OWI0MDcgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42OTI2NTcwMDAwMDAwMDQsIC03OS4yNjQ4NDgxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2RlYjgzOGZlMmFlZjQ2YzdhZjMxODU1MTYyYTQxNDgxID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81YjMwMWE2NzM2MWY0ZWY3ODU5YWIzZjljZTBlMWQzZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNWIzMDFhNjczNjFmNGVmNzg1OWFiM2Y5Y2UwZTFkM2QiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkJpcmNoIENsaWZmLCBDbGlmZnNpZGUgV2VzdCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kZWI4MzhmZTJhZWY0NmM3YWYzMTg1NTE2MmE0MTQ4MS5zZXRDb250ZW50KGh0bWxfNWIzMDFhNjczNjFmNGVmNzg1OWFiM2Y5Y2UwZTFkM2QpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2EyZmE0ZTkxMzFhZjRiYThhZjliNjYzZjg5OTliNDA3LmJpbmRQb3B1cChwb3B1cF9kZWI4MzhmZTJhZWY0NmM3YWYzMTg1NTE2MmE0MTQ4MSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMjU4YTFmMzEzODNlNDdjZGEyYzE4ZDBlZTdhNDJjOGQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43NzAxMTk5LCAtNzkuNDA4NDkyNzk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMzMwMjdlMDJjYjkxNDUyOGJhZjU5OWY4NzA4MzUxMzUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIzMTczOThhYjU5NTRmMDQ5YWIyMjhjZTYyMWIxOGRkID0gJChgPGRpdiBpZD0iaHRtbF8yMzE3Mzk4YWI1OTU0ZjA0OWFiMjI4Y2U2MjFiMThkZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgV2lsbG93ZGFsZSBFYXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzMzMDI3ZTAyY2I5MTQ1MjhiYWY1OTlmODcwODM1MTM1LnNldENvbnRlbnQoaHRtbF8yMzE3Mzk4YWI1OTU0ZjA0OWFiMjI4Y2U2MjFiMThkZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjU4YTFmMzEzODNlNDdjZGEyYzE4ZDBlZTdhNDJjOGQuYmluZFBvcHVwKHBvcHVwXzMzMDI3ZTAyY2I5MTQ1MjhiYWY1OTlmODcwODM1MTM1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMDAyMzQxNGQ3ZmY0YmFjOWNkMzA0ZjE5OTVmODRhZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc2MTYzMTMsIC03OS41MjA5OTk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF82N2Y0NzlhNjI4MWU0MWZiOTMzNTk5ZTJkNTgxMjc2ZSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDg0NzViNDlhMGE1NGRhMzgwMTY5MzUyNTc2YWVlODggPSAkKGA8ZGl2IGlkPSJodG1sXzQ4NDc1YjQ5YTBhNTRkYTM4MDE2OTM1MjU3NmFlZTg4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Eb3duc3ZpZXcgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNjdmNDc5YTYyODFlNDFmYjkzMzU5OWUyZDU4MTI3NmUuc2V0Q29udGVudChodG1sXzQ4NDc1YjQ5YTBhNTRkYTM4MDE2OTM1MjU3NmFlZTg4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMDAyMzQxNGQ3ZmY0YmFjOWNkMzA0ZjE5OTVmODRhZi5iaW5kUG9wdXAocG9wdXBfNjdmNDc5YTYyODFlNDFmYjkzMzU5OWUyZDU4MTI3NmUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2EwMGEzNjQxN2QyZjQzMDRiZmE5MmMyOTFlZmUyMjJiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzI4MDIwNSwgLTc5LjM4ODc5MDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOWFjNTRmOGJkYzU0NDRhMzhmZjE3MTNkZGU1ZTk3NTEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzdjZGY1OTZmN2VlZDRlODZiNjQ3NTBkN2MwOTdmMmZiID0gJChgPGRpdiBpZD0iaHRtbF83Y2RmNTk2ZjdlZWQ0ZTg2YjY0NzUwZDdjMDk3ZjJmYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TGF3cmVuY2UgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85YWM1NGY4YmRjNTQ0NGEzOGZmMTcxM2RkZTVlOTc1MS5zZXRDb250ZW50KGh0bWxfN2NkZjU5NmY3ZWVkNGU4NmI2NDc1MGQ3YzA5N2YyZmIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2EwMGEzNjQxN2QyZjQzMDRiZmE5MmMyOTFlZmUyMjJiLmJpbmRQb3B1cChwb3B1cF85YWM1NGY4YmRjNTQ0NGEzOGZmMTcxM2RkZTVlOTc1MSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjk0ZTM3OGY4YWVkNGRmMjhlZGNiN2JlMDUwM2ZlMWIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MTE2OTQ4LCAtNzkuNDE2OTM1NTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzU4ZDY3NDljNjEyNDQwMmQ5N2UyNDFmNWM0NTM5OTdmID0gJChgPGRpdiBpZD0iaHRtbF81OGQ2NzQ5YzYxMjQ0MDJkOTdlMjQxZjVjNDUzOTk3ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Um9zZWxhd24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUuc2V0Q29udGVudChodG1sXzU4ZDY3NDljNjEyNDQwMmQ5N2UyNDFmNWM0NTM5OTdmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82OTRlMzc4ZjhhZWQ0ZGYyOGVkY2I3YmUwNTAzZmUxYi5iaW5kUG9wdXAocG9wdXBfMDYwMTE5Y2E0MDExNDM0N2JjYmIyYjUxZmNkYzRjMGUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2E3ODk1MzhhZjY2MjRmZTdiMjE2Y2YwZTA5MjcyN2Y2ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjczMTg1Mjk5OTk5OTksIC03OS40ODcyNjE5MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNGJhYTJjNTM4Mjg4NDQwOGE5MDVhM2NhNTlhZTFjMzQgPSAkKGA8ZGl2IGlkPSJodG1sXzRiYWEyYzUzODI4ODQ0MDhhOTA1YTNjYTU5YWUxYzM0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFRoZSBKdW5jdGlvbiBOb3J0aCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MC5zZXRDb250ZW50KGh0bWxfNGJhYTJjNTM4Mjg4NDQwOGE5MDVhM2NhNTlhZTFjMzQpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2E3ODk1MzhhZjY2MjRmZTdiMjE2Y2YwZTA5MjcyN2Y2LmJpbmRQb3B1cChwb3B1cF8yZjRkYmFjNTU3ZmU0NTE1YjdjMzI1Y2RjZTBlZTg1MCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMDM2MzRjYmVhZGZjNGM4ZGJiZGJkN2Q4MzZiZmU5OWQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDY4NzYsIC03OS41MTgxODg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8xYTZlOTAwMTljZjI0M2E2YTVkYzEzNTJhZDdiNDUyNCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfM2JlZDIyYWIzYzJkNDBjM2E5Nzk5ZTNiZmM2M2I2MTQgPSAkKGA8ZGl2IGlkPSJodG1sXzNiZWQyMmFiM2MyZDQwYzNhOTc5OWUzYmZjNjNiNjE0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XZXN0b24gQ2x1c3RlciAwLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMWE2ZTkwMDE5Y2YyNDNhNmE1ZGMxMzUyYWQ3YjQ1MjQuc2V0Q29udGVudChodG1sXzNiZWQyMmFiM2MyZDQwYzNhOTc5OWUzYmZjNjNiNjE0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wMzYzNGNiZWFkZmM0YzhkYmJkYmQ3ZDgzNmJmZTk5ZC5iaW5kUG9wdXAocG9wdXBfMWE2ZTkwMDE5Y2YyNDNhNmE1ZGMxMzUyYWQ3YjQ1MjQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzkxYjUwZjliNWNmYjRlMGVhYzI5YzNkODNhZmIxMDQwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzU3NDA5NiwgLTc5LjI3MzMwNDAwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lM2MzN2UzZGFjYWM0Y2QwOTMwYzNhODU0Y2VmN2UyZSA9ICQoYDxkaXYgaWQ9Imh0bWxfZTNjMzdlM2RhY2FjNGNkMDkzMGMzYTg1NGNlZjdlMmUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRvcnNldCBQYXJrLCBXZXhmb3JkIEhlaWdodHMsIFNjYXJib3JvdWdoIFRvd24gQ2VudHJlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyLnNldENvbnRlbnQoaHRtbF9lM2MzN2UzZGFjYWM0Y2QwOTMwYzNhODU0Y2VmN2UyZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTFiNTBmOWI1Y2ZiNGUwZWFjMjljM2Q4M2FmYjEwNDAuYmluZFBvcHVwKHBvcHVwX2QyMGM0OTg5NjI3NjRmYjdhMDljNGI4NjY1NDY5ZWMyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84ZTMyZTUzYWU1ZmU0NTc3OTViOTlkOWM4OWVmM2M0NSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1Mjc1ODI5OTk5OTk5NiwgLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiNmZjAwMDAiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiI2ZmMDAwMCIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzNhYjlkNzYwY2U5NGIzNmI2NjUwYmM1OGEyODJkOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzFmODI4MDQyOTBjYTQ3YjVhYTkwNTEwNzU2OTAwZGIyID0gJChgPGRpdiBpZD0iaHRtbF8xZjgyODA0MjkwY2E0N2I1YWE5MDUxMDc1NjkwMGRiMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+WW9yayBNaWxscyBXZXN0IENsdXN0ZXIgMC4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzczYWI5ZDc2MGNlOTRiMzZiNjY1MGJjNThhMjgyZDlmLnNldENvbnRlbnQoaHRtbF8xZjgyODA0MjkwY2E0N2I1YWE5MDUxMDc1NjkwMGRiMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOGUzMmU1M2FlNWZlNDU3Nzk1Yjk5ZDljODllZjNjNDUuYmluZFBvcHVwKHBvcHVwXzczYWI5ZDc2MGNlOTRiMzZiNjY1MGJjNThhMjgyZDlmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8wMmI5NGQzYThkNDU0MmUxYTlmZTNlMTI3MmQ5YTc4YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxMjc1MTEsIC03OS4zOTAxOTc1XSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2JkMjBiODcyNGNmNTQ0OTdhYjY2MWY3Y2Q0ODQ4NjRjID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9mZWM2ZWE4ZTliZTU0ZDdlYmZlN2RmZGUzMjFlM2IxZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZmVjNmVhOGU5YmU1NGQ3ZWJmZTdkZmRlMzIxZTNiMWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkRhdmlzdmlsbGUgTm9ydGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfYmQyMGI4NzI0Y2Y1NDQ5N2FiNjYxZjdjZDQ4NDg2NGMuc2V0Q29udGVudChodG1sX2ZlYzZlYThlOWJlNTRkN2ViZmU3ZGZkZTMyMWUzYjFmKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wMmI5NGQzYThkNDU0MmUxYTlmZTNlMTI3MmQ5YTc4Yi5iaW5kUG9wdXAocG9wdXBfYmQyMGI4NzI0Y2Y1NDQ5N2FiNjYxZjdjZDQ4NDg2NGMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI0N2QxZTM3ZjMzNDQ4OTE5NmEyM2IwNmM1MTY0Njc1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2OTQ3NiwgLTc5LjQxMTMwNzIwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcxZDA4M2Q1ZmViNzQyNDBiYTkwN2ZmY2E4NDQyYzdlID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8xZWM5MzA4MmE0NWQ0ZDNiYTM1ODNmMGNjMmQ4MDM5NyA9ICQoYDxkaXYgaWQ9Imh0bWxfMWVjOTMwODJhNDVkNGQzYmEzNTgzZjBjYzJkODAzOTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkZvcmVzdCBIaWxsIE5vcnRoICZhbXA7IFdlc3QsIEZvcmVzdCBIaWxsIFJvYWQgUGFyayBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF83MWQwODNkNWZlYjc0MjQwYmE5MDdmZmNhODQ0MmM3ZS5zZXRDb250ZW50KGh0bWxfMWVjOTMwODJhNDVkNGQzYmEzNTgzZjBjYzJkODAzOTcpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzI0N2QxZTM3ZjMzNDQ4OTE5NmEyM2IwNmM1MTY0Njc1LmJpbmRQb3B1cChwb3B1cF83MWQwODNkNWZlYjc0MjQwYmE5MDdmZmNhODQ0MmM3ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjFlMGFmNDkxODUxNGRiY2FiZTM0NzE0ZmU5MzE3YWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NjE2MDgzLCAtNzkuNDY0NzYzMjk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiZTY0NzM3YWE2NjRlNDRhYmEwZmU1NmYxN2I4NjA3ID0gJChgPGRpdiBpZD0iaHRtbF80YmU2NDczN2FhNjY0ZTQ0YWJhMGZlNTZmMTdiODYwNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+SGlnaCBQYXJrLCBUaGUgSnVuY3Rpb24gU291dGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMuc2V0Q29udGVudChodG1sXzRiZTY0NzM3YWE2NjRlNDRhYmEwZmU1NmYxN2I4NjA3KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl82MWUwYWY0OTE4NTE0ZGJjYWJlMzQ3MTRmZTkzMTdhYy5iaW5kUG9wdXAocG9wdXBfNzU4Njg0OWRmMTllNDljYzg0ZjcxZmM4NGQyYjgzMzMpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzEwYTAzNTAwZDg4MzQ5MDc4NzNmNWYzODNlNjU1ZGZhID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjk2MzE5LCAtNzkuNTMyMjQyNDAwMDAwMDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNDY0NzdiMzdlOGM2NDliYjlhNjNjM2UyOGE0NzcwOTggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2UzZDY3OGVmMzgzYTQzMWZhM2RiNmRkYzI4Y2M5ZTJkID0gJChgPGRpdiBpZD0iaHRtbF9lM2Q2NzhlZjM4M2E0MzFmYTNkYjZkZGMyOGNjOWUyZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2VzdG1vdW50IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzQ2NDc3YjM3ZThjNjQ5YmI5YTYzYzNlMjhhNDc3MDk4LnNldENvbnRlbnQoaHRtbF9lM2Q2NzhlZjM4M2E0MzFmYTNkYjZkZGMyOGNjOWUyZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMTBhMDM1MDBkODgzNDkwNzg3M2Y1ZjM4M2U2NTVkZmEuYmluZFBvcHVwKHBvcHVwXzQ2NDc3YjM3ZThjNjQ5YmI5YTYzYzNlMjhhNDc3MDk4KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xNzRhNGM2ZjNhOTk0Zjg0YTE3NDNlNGQ3NWIyNjhlMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc1MDA3MTUwMDAwMDAwNCwgLTc5LjI5NTg0OTFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2QgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzczN2RjMGVhZDNlNzRmNjc4NzYyOTNmNTcyMmZlOTE5ID0gJChgPGRpdiBpZD0iaHRtbF83MzdkYzBlYWQzZTc0ZjY3ODc2MjkzZjU3MjJmZTkxOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2V4Zm9yZCwgTWFyeXZhbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2Quc2V0Q29udGVudChodG1sXzczN2RjMGVhZDNlNzRmNjc4NzYyOTNmNTcyMmZlOTE5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8xNzRhNGM2ZjNhOTk0Zjg0YTE3NDNlNGQ3NWIyNjhlMy5iaW5kUG9wdXAocG9wdXBfZGQ3ZGE2MDMxM2U3NGQ0YmE3YmQ0NDQzZTY4Y2I2Y2QpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzNmMDI3YjZlYzUzYTQ2N2M4ZmQwNGU5YWJjNWJhOGFiID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgyNzM2NCwgLTc5LjQ0MjI1OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZjlkNDFkOTFhYmZjNGNhMzk2OGE5YTRmMTdmOWMwYmEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzRiMWE1NDg1OTA0NjRmZTk4NDAzODZmNmViNjgyYWExID0gJChgPGRpdiBpZD0iaHRtbF80YjFhNTQ4NTkwNDY0ZmU5ODQwMzg2ZjZlYjY4MmFhMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2lsbG93ZGFsZSwgV2lsbG93ZGFsZSBXZXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2Y5ZDQxZDkxYWJmYzRjYTM5NjhhOWE0ZjE3ZjljMGJhLnNldENvbnRlbnQoaHRtbF80YjFhNTQ4NTkwNDY0ZmU5ODQwMzg2ZjZlYjY4MmFhMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfM2YwMjdiNmVjNTNhNDY3YzhmZDA0ZTlhYmM1YmE4YWIuYmluZFBvcHVwKHBvcHVwX2Y5ZDQxZDkxYWJmYzRjYTM5NjhhOWE0ZjE3ZjljMGJhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iYTE5ZDM4ZDcyZjI0MDRkYWZhYTI1NDZlYjI2Y2U5ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcxNTM4MzQsIC03OS40MDU2Nzg0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF85N2FlNTcyZTBkYjk0NWVhYTYxNGEzNmY2ZTJiNGVlYiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjUyMWUyMzZhNzAyNDUxZDk4MzEzNTg0NWVkNWNlZDQgPSAkKGA8ZGl2IGlkPSJodG1sX2I1MjFlMjM2YTcwMjQ1MWQ5ODMxMzU4NDVlZDVjZWQ0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Ob3J0aCBUb3JvbnRvIFdlc3QsIExhd3JlbmNlIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOTdhZTU3MmUwZGI5NDVlYWE2MTRhMzZmNmUyYjRlZWIuc2V0Q29udGVudChodG1sX2I1MjFlMjM2YTcwMjQ1MWQ5ODMxMzU4NDVlZDVjZWQ0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iYTE5ZDM4ZDcyZjI0MDRkYWZhYTI1NDZlYjI2Y2U5ZC5iaW5kUG9wdXAocG9wdXBfOTdhZTU3MmUwZGI5NDVlYWE2MTRhMzZmNmUyYjRlZWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2U5NDE2YmM2MGQyYjRmMzRhYWI3ZmQzNzY3NTFjMmMxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjcyNzA5NywgLTc5LjQwNTY3ODQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84MDc5NjFhOGJhNmI0ZmE5YjM3NDFlMjFiY2Q2MWEzOCA9ICQoYDxkaXYgaWQ9Imh0bWxfODA3OTYxYThiYTZiNGZhOWIzNzQxZTIxYmNkNjFhMzgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlRoZSBBbm5leCwgTm9ydGggTWlkdG93biwgWW9ya3ZpbGxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwLnNldENvbnRlbnQoaHRtbF84MDc5NjFhOGJhNmI0ZmE5YjM3NDFlMjFiY2Q2MWEzOCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZTk0MTZiYzYwZDJiNGYzNGFhYjdmZDM3Njc1MWMyYzEuYmluZFBvcHVwKHBvcHVwX2QwY2MxNGFkNjYxMzQyNzNiNzQwNDJkM2M1NWIyNDQwKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iNmE1MWE3YWRiYmY0ZjI4OTI2OGZiMmYzNDFjOWY4MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY0ODk1OTcsIC03OS40NTYzMjVdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOThjOGU2ZjUyYmM2NDZmMzk5NzdjOGY0Njc5MWI4MzIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg1MWU4NjdmMzE2NzQ5NDZiYjIyNWQxMDM2NzhhNTMyID0gJChgPGRpdiBpZD0iaHRtbF84NTFlODY3ZjMxNjc0OTQ2YmIyMjVkMTAzNjc4YTUzMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFya2RhbGUsIFJvbmNlc3ZhbGxlcyBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85OGM4ZTZmNTJiYzY0NmYzOTk3N2M4ZjQ2NzkxYjgzMi5zZXRDb250ZW50KGh0bWxfODUxZTg2N2YzMTY3NDk0NmJiMjI1ZDEwMzY3OGE1MzIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2I2YTUxYTdhZGJiZjRmMjg5MjY4ZmIyZjM0MWM5ZjgxLmJpbmRQb3B1cChwb3B1cF85OGM4ZTZmNTJiYzY0NmYzOTk3N2M4ZjQ2NzkxYjgzMikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfODhhMTk1MGU5OTRlNDc0MzhjNGExYWJlNDE4ZWQwMjEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MzY5NjU2LCAtNzkuNjE1ODE4OTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfOTVlNThmMDc3MTY2NDgzMzg5MGQ4MmJmZGU5MWFmOWYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzlhYTIyMTZkMTE5ZTRjNDlhOGExN2I5MzNkOGQ2MDRiID0gJChgPGRpdiBpZD0iaHRtbF85YWEyMjE2ZDExOWU0YzQ5YThhMTdiOTMzZDhkNjA0YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2FuYWRhIFBvc3QgR2F0ZXdheSBQcm9jZXNzaW5nIENlbnRyZSBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF85NWU1OGYwNzcxNjY0ODMzODkwZDgyYmZkZTkxYWY5Zi5zZXRDb250ZW50KGh0bWxfOWFhMjIxNmQxMTllNGM0OWE4YTE3YjkzM2Q4ZDYwNGIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzg4YTE5NTBlOTk0ZTQ3NDM4YzRhMWFiZTQxOGVkMDIxLmJpbmRQb3B1cChwb3B1cF85NWU1OGYwNzcxNjY0ODMzODkwZDgyYmZkZTkxYWY5ZikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWJhY2FhMDFmNTkwNGQ5Y2ExYjU5NGI4NzM4NGEyYzEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODg5MDU0LCAtNzkuNTU0NzI0NDAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2E1OWJiNGZlNDZiMzRjNjJiMWJhMWIwZGNkNzg2ODY1ID0gJChgPGRpdiBpZD0iaHRtbF9hNTliYjRmZTQ2YjM0YzYyYjFiYTFiMGRjZDc4Njg2NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+S2luZ3N2aWV3IFZpbGxhZ2UsIFN0LiBQaGlsbGlwcywgTWFydGluIEdyb3ZlIEdhcmRlbnMsIFJpY2h2aWV3IEdhcmRlbnMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIuc2V0Q29udGVudChodG1sX2E1OWJiNGZlNDZiMzRjNjJiMWJhMWIwZGNkNzg2ODY1KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9hYmFjYWEwMWY1OTA0ZDljYTFiNTk0Yjg3Mzg0YTJjMS5iaW5kUG9wdXAocG9wdXBfZDY0NjQxNDYxZjJkNGE2ZDk3ZWRhNGM5NWNkMGNkYWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UwYTk1OWRmZTg0NDQ4Y2JiM2JiYjYzZmE4MGZjMjJlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzk0MjAwMywgLTc5LjI2MjAyOTQwMDAwMDAyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzUyZjRjY2Y2NzkxMDRkZDNiNzdkOGYzNDAwNjQxNGM0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF8wYzlkMjAzYmRmNzg0Y2EyYThlZTY1MjFiNzQwMWY3MCA9ICQoYDxkaXYgaWQ9Imh0bWxfMGM5ZDIwM2JkZjc4NGNhMmE4ZWU2NTIxYjc0MDFmNzAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkFnaW5jb3VydCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF81MmY0Y2NmNjc5MTA0ZGQzYjc3ZDhmMzQwMDY0MTRjNC5zZXRDb250ZW50KGh0bWxfMGM5ZDIwM2JkZjc4NGNhMmE4ZWU2NTIxYjc0MDFmNzApOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2UwYTk1OWRmZTg0NDQ4Y2JiM2JiYjYzZmE4MGZjMjJlLmJpbmRQb3B1cChwb3B1cF81MmY0Y2NmNjc5MTA0ZGQzYjc3ZDhmMzQwMDY0MTRjNCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjQ5OTAxYWNkOTYzNDllMDhhMjc2ZjJhOGQyODYyOTAgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My43MDQzMjQ0LCAtNzkuMzg4NzkwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8zZTRiNTQ3OWY0OGU0MjRkYWU3YTUyNDBjZmIxZTI3OSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzlkYmE4ZmRmZDgyNDkwZWI1Y2M0ZTU5YTQ2OGExMWUgPSAkKGA8ZGl2IGlkPSJodG1sX2M5ZGJhOGZkZmQ4MjQ5MGViNWNjNGU1OWE0NjhhMTFlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5EYXZpc3ZpbGxlIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzNlNGI1NDc5ZjQ4ZTQyNGRhZTdhNTI0MGNmYjFlMjc5LnNldENvbnRlbnQoaHRtbF9jOWRiYThmZGZkODI0OTBlYjVjYzRlNTlhNDY4YTExZSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfNjQ5OTAxYWNkOTYzNDllMDhhMjc2ZjJhOGQyODYyOTAuYmluZFBvcHVwKHBvcHVwXzNlNGI1NDc5ZjQ4ZTQyNGRhZTdhNTI0MGNmYjFlMjc5KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8xYWYzMDY5NmViNDE0ODViODZlYmQxMGQyNjAzOWJmNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2MjY5NTYsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzgxZjQ5ZTc4ODc5YzRmOTFhNjc5NzY5YTcxOTVlMDY1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF84NzVmZTViMzk1MGM0NTBkODVkYzljYTQ3NjkyOGRlYSA9ICQoYDxkaXYgaWQ9Imh0bWxfODc1ZmU1YjM5NTBjNDUwZDg1ZGM5Y2E0NzY5MjhkZWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlVuaXZlcnNpdHkgb2YgVG9yb250bywgSGFyYm9yZCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF84MWY0OWU3ODg3OWM0ZjkxYTY3OTc2OWE3MTk1ZTA2NS5zZXRDb250ZW50KGh0bWxfODc1ZmU1YjM5NTBjNDUwZDg1ZGM5Y2E0NzY5MjhkZWEpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzFhZjMwNjk2ZWI0MTQ4NWI4NmViZDEwZDI2MDM5YmY2LmJpbmRQb3B1cChwb3B1cF84MWY0OWU3ODg3OWM0ZjkxYTY3OTc2OWE3MTk1ZTA2NSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2M1YTY3Zjc0MjU3NDVjMTk5Y2MwZWViNDBhMWJhOGYgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NTE1NzA2LCAtNzkuNDg0NDQ5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9lNGFmMmM1YmI4YmY0ZDQzOGU0Y2RiYTA1NDJiNWFiYSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjE2NGZkM2Q5ZmNkNDZiMWI1MGYzOTI0M2FlZGNjZTMgPSAkKGA8ZGl2IGlkPSJodG1sX2IxNjRmZDNkOWZjZDQ2YjFiNTBmMzkyNDNhZWRjY2UzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SdW5ueW1lZGUsIFN3YW5zZWEgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTRhZjJjNWJiOGJmNGQ0MzhlNGNkYmEwNTQyYjVhYmEuc2V0Q29udGVudChodG1sX2IxNjRmZDNkOWZjZDQ2YjFiNTBmMzkyNDNhZWRjY2UzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9jYzVhNjdmNzQyNTc0NWMxOTljYzBlZWI0MGExYmE4Zi5iaW5kUG9wdXAocG9wdXBfZTRhZjJjNWJiOGJmNGQ0MzhlNGNkYmEwNTQyYjVhYmEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q3MDRiNjliN2NlMzRjODE4MWQyOTk3MTMzZGNjMDAwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzgxNjM3NSwgLTc5LjMwNDMwMjFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYmJjODc0NGYwMTI1NDFmOTljYjVlMWQ2NzA1YTNiNmMgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2EyNjZmODY2YWUxMDQ1MzY4ZGExMjAyODE5MjBhMDJmID0gJChgPGRpdiBpZD0iaHRtbF9hMjY2Zjg2NmFlMTA0NTM2OGRhMTIwMjgxOTIwYTAyZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q2xhcmtzIENvcm5lcnMsIFRhbSBPJiMzOTtTaGFudGVyLCBTdWxsaXZhbiBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9iYmM4NzQ0ZjAxMjU0MWY5OWNiNWUxZDY3MDVhM2I2Yy5zZXRDb250ZW50KGh0bWxfYTI2NmY4NjZhZTEwNDUzNjhkYTEyMDI4MTkyMGEwMmYpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q3MDRiNjliN2NlMzRjODE4MWQyOTk3MTMzZGNjMDAwLmJpbmRQb3B1cChwb3B1cF9iYmM4NzQ0ZjAxMjU0MWY5OWNiNWUxZDY3MDVhM2I2YykKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOTdmODNiMmU3M2ZkNDQxZGI5ZTg4ZThhNzhlMTFmMzIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODk1NzQzLCAtNzkuMzgzMTU5OTAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYmUwZDZjOGFjZmFlNGE4YzkxYTgxMWQ0OTkyYzQwMmEgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzNmYjYyODMxY2EzMzRiODNhNjhjMjBlMGM0ODQ3OTRkID0gJChgPGRpdiBpZD0iaHRtbF8zZmI2MjgzMWNhMzM0YjgzYTY4YzIwZTBjNDg0Nzk0ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TW9vcmUgUGFyaywgU3VtbWVyaGlsbCBFYXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2JlMGQ2YzhhY2ZhZTRhOGM5MWE4MTFkNDk5MmM0MDJhLnNldENvbnRlbnQoaHRtbF8zZmI2MjgzMWNhMzM0YjgzYTY4YzIwZTBjNDg0Nzk0ZCk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfOTdmODNiMmU3M2ZkNDQxZGI5ZTg4ZThhNzhlMTFmMzIuYmluZFBvcHVwKHBvcHVwX2JlMGQ2YzhhY2ZhZTRhOGM5MWE4MTFkNDk5MmM0MDJhKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kZjBkZmIyZjgzMmI0OGIwOTU5NDkwMjRmNzI0YzhjMiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY1MzIwNTcsIC03OS40MDAwNDkzXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9kMzU3ZDQyZTdiNDE0N2IwOTUxY2I5NTNiMzA2ZGY4MyA9ICQoYDxkaXYgaWQ9Imh0bWxfZDM1N2Q0MmU3YjQxNDdiMDk1MWNiOTUzYjMwNmRmODMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPktlbnNpbmd0b24gTWFya2V0LCBDaGluYXRvd24sIEdyYW5nZSBQYXJrIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkLnNldENvbnRlbnQoaHRtbF9kMzU3ZDQyZTdiNDE0N2IwOTUxY2I5NTNiMzA2ZGY4Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZGYwZGZiMmY4MzJiNDhiMDk1OTQ5MDI0ZjcyNGM4YzIuYmluZFBvcHVwKHBvcHVwXzcwNDQ1YTdmNDQ0YjQxNWQ4ZGQ5YzBlOWMxMDlmNzdkKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zNmZjMmM4ZGE0ZGM0YTI0YTViYTQwMjMwNmM1YjBjMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjgxNTI1MjIsIC03OS4yODQ1NzcyXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjZmYwMDAwIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiNmZjAwMDAiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2Q3OTdjY2FlNDE4ZDRlYjk4ZDlkNTQ5NGE1MDgyMzc0ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF81N2IxZDY5ZjI2ZDk0MGZjYTJlZWQwNTBjYmQ1ZGExMiA9ICQoYDxkaXYgaWQ9Imh0bWxfNTdiMWQ2OWYyNmQ5NDBmY2EyZWVkMDUwY2JkNWRhMTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbGxpa2VuLCBBZ2luY291cnQgTm9ydGgsIFN0ZWVsZXMgRWFzdCwgTCYjMzk7QW1vcmVhdXggRWFzdCBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9kNzk3Y2NhZTQxOGQ0ZWI5OGQ5ZDU0OTRhNTA4MjM3NC5zZXRDb250ZW50KGh0bWxfNTdiMWQ2OWYyNmQ5NDBmY2EyZWVkMDUwY2JkNWRhMTIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzM2ZmMyYzhkYTRkYzRhMjRhNWJhNDAyMzA2YzViMGMwLmJpbmRQb3B1cChwb3B1cF9kNzk3Y2NhZTQxOGQ0ZWI5OGQ5ZDU0OTRhNTA4MjM3NCkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZmQwZTYxNGRiODQ1NGRiZmI4ODA1OGQxYmE2MDYwMmQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42ODY0MTIyOTk5OTk5OSwgLTc5LjQwMDA0OTNdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzg4ODk2OWZmMDMyNjRiYzc5MjgzZTMyNzRmNzM0ODM5ID0gJChgPGRpdiBpZD0iaHRtbF84ODg5NjlmZjAzMjY0YmM3OTI4M2UzMjc0ZjczNDgzOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3VtbWVyaGlsbCBXZXN0LCBSYXRobmVsbHksIFNvdXRoIEhpbGwsIEZvcmVzdCBIaWxsIFNFLCBEZWVyIFBhcmsgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkuc2V0Q29udGVudChodG1sXzg4ODk2OWZmMDMyNjRiYzc5MjgzZTMyNzRmNzM0ODM5KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9mZDBlNjE0ZGI4NDU0ZGJmYjg4MDU4ZDFiYTYwNjAyZC5iaW5kUG9wdXAocG9wdXBfZTJmM2RjMmM5YzRjNDllNGFhYzViMThkZTg0MDAxNzkpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzAwODY2Njk3ZDZmNzQxNzc5NDVjNmE5Yjk5MDQ5MjcyID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4OTQ2NywgLTc5LjM5NDQxOTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYzIyYTYwZWNhYTAwNGViZTgwZjZkMTFjZDFlMjU1NmUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzI0MWIzZDFhMzUwNzQ0ZGZhMTY4OTY0NjdkZDNlMjc1ID0gJChgPGRpdiBpZD0iaHRtbF8yNDFiM2QxYTM1MDc0NGRmYTE2ODk2NDY3ZGQzZTI3NSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Q04gVG93ZXIsIEtpbmcgYW5kIFNwYWRpbmEsIFJhaWx3YXkgTGFuZHMsIEhhcmJvdXJmcm9udCBXZXN0LCBCYXRodXJzdCBRdWF5LCBTb3V0aCBOaWFnYXJhLCBJc2xhbmQgYWlycG9ydCBDbHVzdGVyIDEuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9jMjJhNjBlY2FhMDA0ZWJlODBmNmQxMWNkMWUyNTU2ZS5zZXRDb250ZW50KGh0bWxfMjQxYjNkMWEzNTA3NDRkZmExNjg5NjQ2N2RkM2UyNzUpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyXzAwODY2Njk3ZDZmNzQxNzc5NDVjNmE5Yjk5MDQ5MjcyLmJpbmRQb3B1cChwb3B1cF9jMjJhNjBlY2FhMDA0ZWJlODBmNmQxMWNkMWUyNTU2ZSkKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfOWU5NTVjOGM1ZGFlNDA4YmE1YTNkNGFlNTQzOGJkMjggPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42MDU2NDY2LCAtNzkuNTAxMzIwNzAwMDAwMDFdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzUyYzAzZGEyZThkNDRmOTFiODQ3ODcyOTYxZTMwYmVhID0gJChgPGRpdiBpZD0iaHRtbF81MmMwM2RhMmU4ZDQ0ZjkxYjg0Nzg3Mjk2MWUzMGJlYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+TmV3IFRvcm9udG8sIE1pbWljbyBTb3V0aCwgSHVtYmVyIEJheSBTaG9yZXMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUuc2V0Q29udGVudChodG1sXzUyYzAzZGEyZThkNDRmOTFiODQ3ODcyOTYxZTMwYmVhKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85ZTk1NWM4YzVkYWU0MDhiYTVhM2Q0YWU1NDM4YmQyOC5iaW5kUG9wdXAocG9wdXBfZDI5OWE5OTUyNjE2NDVlOWI4OGIyMjA1Zjc2NjRjZTUpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Y4MjM1MTM0MTgxZjQwMmJhYzZiNjVjMzJlY2YyODM0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNzM5NDE2Mzk5OTk5OTk2LCAtNzkuNTg4NDM2OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81YjBlNzcxN2NlZTY0MWViOTRmNjEwMjdiMTAzMWI3MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYjZkZmMxZWFjNGI4NGJmNmE3MmViYjA3MGFkOWY1MGIgPSAkKGA8ZGl2IGlkPSJodG1sX2I2ZGZjMWVhYzRiODRiZjZhNzJlYmIwNzBhZDlmNTBiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Tb3V0aCBTdGVlbGVzLCBTaWx2ZXJzdG9uZSwgSHVtYmVyZ2F0ZSwgSmFtZXN0b3duLCBNb3VudCBPbGl2ZSwgQmVhdW1vbmQgSGVpZ2h0cywgVGhpc3RsZXRvd24sIEFsYmlvbiBHYXJkZW5zIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzViMGU3NzE3Y2VlNjQxZWI5NGY2MTAyN2IxMDMxYjcyLnNldENvbnRlbnQoaHRtbF9iNmRmYzFlYWM0Yjg0YmY2YTcyZWJiMDcwYWQ5ZjUwYik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZjgyMzUxMzQxODFmNDAyYmFjNmI2NWMzMmVjZjI4MzQuYmluZFBvcHVwKHBvcHVwXzViMGU3NzE3Y2VlNjQxZWI5NGY2MTAyN2IxMDMxYjcyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yNGU1MjNiMDE2OGQ0MGIwYjQzYjE1ZjU5OTRkYTQ4YiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjc5OTUyNTIwMDAwMDAwNSwgLTc5LjMxODM4ODddLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZTA1MGRiZTZlYjlhNGE4YWFhZDAyMTMyZTgxZDM5MjYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzIyZjg2YjMwN2E5MTQyY2FiYWU4M2UzOGM3MTAxZGUyID0gJChgPGRpdiBpZD0iaHRtbF8yMmY4NmIzMDdhOTE0MmNhYmFlODNlMzhjNzEwMWRlMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3RlZWxlcyBXZXN0LCBMJiMzOTtBbW9yZWF1eCBXZXN0IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2UwNTBkYmU2ZWI5YTRhOGFhYWQwMjEzMmU4MWQzOTI2LnNldENvbnRlbnQoaHRtbF8yMmY4NmIzMDdhOTE0MmNhYmFlODNlMzhjNzEwMWRlMik7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfMjRlNTIzYjAxNjhkNDBiMGI0M2IxNWY1OTk0ZGE0OGIuYmluZFBvcHVwKHBvcHVwX2UwNTBkYmU2ZWI5YTRhOGFhYWQwMjEzMmU4MWQzOTI2KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9kNDY2N2I0YWNkMWY0MzQxYjZiZDdkMDdiOTI4MzZkMyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY3OTU2MjYsIC03OS4zNzc1Mjk0MDAwMDAwMV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiI2ZmMDAwMCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjZmYwMDAwIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDk4ZjFjN2EwNTVmNGU1YWEyYWEzYWVlODZhOThhYWIgPSAkKGA8ZGl2IGlkPSJodG1sXzQ5OGYxYzdhMDU1ZjRlNWFhMmFhM2FlZTg2YTk4YWFiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Sb3NlZGFsZSBDbHVzdGVyIDAuMDwvZGl2PmApWzBdOwogICAgICAgICAgICBwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNi5zZXRDb250ZW50KGh0bWxfNDk4ZjFjN2EwNTVmNGU1YWEyYWEzYWVlODZhOThhYWIpOwogICAgICAgIAoKICAgICAgICBjaXJjbGVfbWFya2VyX2Q0NjY3YjRhY2QxZjQzNDFiNmJkN2QwN2I5MjgzNmQzLmJpbmRQb3B1cChwb3B1cF9jNDk3MzNiZWMxNTE0NGRhODNiZjdjMzNkMDZkMjRmNikKICAgICAgICA7CgogICAgICAgIAogICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZWViNGY4OGY4NTE3NGIzZTg1NGU2N2RmZDk1MjgzOTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0My42NDY0MzUyLCAtNzkuMzc0ODQ1OTk5OTk5OTldLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzVlYTA2ODdmMzhkNDRjZDg5M2YxNTUxZWUyODY3OGEzID0gJChgPGRpdiBpZD0iaHRtbF81ZWEwNjg3ZjM4ZDQ0Y2Q4OTNmMTU1MWVlMjg2NzhhMyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+U3RuIEEgUE8gQm94ZXMgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQuc2V0Q29udGVudChodG1sXzVlYTA2ODdmMzhkNDRjZDg5M2YxNTUxZWUyODY3OGEzKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9lZWI0Zjg4Zjg1MTc0YjNlODU0ZTY3ZGZkOTUyODM5OS5iaW5kUG9wdXAocG9wdXBfZWU5ODMxNTY5YzE2NGE3MmE0NDdhMjUzNmI0ZDExMWQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2Q4YmY1ZDI2YjNjMTRjYWU4NDFhYTk1ZmNhYTVhYWI1ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjAyNDEzNzAwMDAwMDEsIC03OS41NDM0ODQwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF8wNzIwNjRlOTQxODg0YzhlODkyNzgxMzhlOGYwYTc5MiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfNDFmZTM1ZDU1YmI5NDE4ZDk1ODA2NTAwNTk1NzVkNDMgPSAkKGA8ZGl2IGlkPSJodG1sXzQxZmUzNWQ1NWJiOTQxOGQ5NTgwNjUwMDU5NTc1ZDQzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5BbGRlcndvb2QsIExvbmcgQnJhbmNoIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwXzA3MjA2NGU5NDE4ODRjOGU4OTI3ODEzOGU4ZjBhNzkyLnNldENvbnRlbnQoaHRtbF80MWZlMzVkNTViYjk0MThkOTU4MDY1MDA1OTU3NWQ0Myk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfZDhiZjVkMjZiM2MxNGNhZTg0MWFhOTVmY2FhNWFhYjUuYmluZFBvcHVwKHBvcHVwXzA3MjA2NGU5NDE4ODRjOGU4OTI3ODEzOGU4ZjBhNzkyKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMDIwNzY5Mzg5Njk0NDAyOTVlNjliYTU4OTBmZDdhNiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjcwNjc0ODI5OTk5OTk5NCwgLTc5LjU5NDA1NDRdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzlkYWM0YTk3ZTNhZDQ1YzQ5YjBiYzg3MGM5MWE1MmY0ID0gJChgPGRpdiBpZD0iaHRtbF85ZGFjNGE5N2UzYWQ0NWM0OWIwYmM4NzBjOTFhNTJmNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Tm9ydGh3ZXN0LCBXZXN0IEh1bWJlciAtIENsYWlydmlsbGUgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDguc2V0Q29udGVudChodG1sXzlkYWM0YTk3ZTNhZDQ1YzQ5YjBiYzg3MGM5MWE1MmY0KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl9iMDIwNzY5Mzg5Njk0NDAyOTVlNjliYTU4OTBmZDdhNi5iaW5kUG9wdXAocG9wdXBfMjUxZjdiMmFmMTc2NDc4NTkyNzA4NzE5YTU2NDQ3NDgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzViNmRlMGU1NDNlYzQwZTg5MjA2M2JiMDAzMDljMzEzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY3OTY3LCAtNzkuMzY3Njc1M10sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF84YjNiY2VkM2ZhOTQ0Y2VhYTc2MTY2ZDhmZTk5NmNmZCA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfZWIyM2ZiZmRkNmNiNGRmY2FkZjc5MTcyNjkyOGQ1OWUgPSAkKGA8ZGl2IGlkPSJodG1sX2ViMjNmYmZkZDZjYjRkZmNhZGY3OTE3MjY5MjhkNTllIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5TdC4gSmFtZXMgVG93biwgQ2FiYmFnZXRvd24gQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfOGIzYmNlZDNmYTk0NGNlYWE3NjE2NmQ4ZmU5OTZjZmQuc2V0Q29udGVudChodG1sX2ViMjNmYmZkZDZjYjRkZmNhZGY3OTE3MjY5MjhkNTllKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl81YjZkZTBlNTQzZWM0MGU4OTIwNjNiYjAwMzA5YzMxMy5iaW5kUG9wdXAocG9wdXBfOGIzYmNlZDNmYTk0NGNlYWE3NjE2NmQ4ZmU5OTZjZmQpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzI4NTk1NzdiYTUxMjRiMDE4YjRjNjA4ZDE1OTJiOTRjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjQ4NDI5MiwgLTc5LjM4MjI4MDJdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0NjggPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sXzE2Yjg2Yjk2Mjc5NDQxMWM4ZjMzMGM3Y2ZjMWYyY2Q4ID0gJChgPGRpdiBpZD0iaHRtbF8xNmI4NmI5NjI3OTQ0MTFjOGYzMzBjN2NmYzFmMmNkOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Rmlyc3QgQ2FuYWRpYW4gUGxhY2UsIFVuZGVyZ3JvdW5kIGNpdHkgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0Njguc2V0Q29udGVudChodG1sXzE2Yjg2Yjk2Mjc5NDQxMWM4ZjMzMGM3Y2ZjMWYyY2Q4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8yODU5NTc3YmE1MTI0YjAxOGI0YzYwOGQxNTkyYjk0Yy5iaW5kUG9wdXAocG9wdXBfNDIyYzhhMDFlMTEyNDdmY2FmNzdjZDIxZTdkNjM0NjgpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzhiN2ZjYWFkN2IzZDRhN2ZiMDY0OWNhYTE2ZGJkMjYzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjUzNjUzNjAwMDAwMDA1LCAtNzkuNTA2OTQzNl0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwMDBmZiIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODAwMGZmIiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF80ODkxZDQ5ZWEzY2E0ZTZlOTMxNTAwMTczYjc5NjViZiA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYTYwMWRiMDE2YjAzNDczOGI3ZjkzMjI5MzE4NThiM2UgPSAkKGA8ZGl2IGlkPSJodG1sX2E2MDFkYjAxNmIwMzQ3MzhiN2Y5MzIyOTMxODU4YjNlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UaGUgS2luZ3N3YXksIE1vbnRnb21lcnkgUm9hZCwgT2xkIE1pbGwgTm9ydGggQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNDg5MWQ0OWVhM2NhNGU2ZTkzMTUwMDE3M2I3OTY1YmYuc2V0Q29udGVudChodG1sX2E2MDFkYjAxNmIwMzQ3MzhiN2Y5MzIyOTMxODU4YjNlKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl84YjdmY2FhZDdiM2Q0YTdmYjA2NDljYWExNmRiZDI2My5iaW5kUG9wdXAocG9wdXBfNDg5MWQ0OWVhM2NhNGU2ZTkzMTUwMDE3M2I3OTY1YmYpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2NjZjhhN2JkODcyYjRkNDNiZDE4OGZlMWI4MDgyNmMxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjY1ODU5OSwgLTc5LjM4MzE1OTkwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1ID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9lYTJiNTY4NTg1YzM0MjE3YTMwZjFjNjZlOTYyNGMyMSA9ICQoYDxkaXYgaWQ9Imh0bWxfZWEyYjU2ODU4NWMzNDIxN2EzMGYxYzY2ZTk2MjRjMjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkNodXJjaCBhbmQgV2VsbGVzbGV5IENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1LnNldENvbnRlbnQoaHRtbF9lYTJiNTY4NTg1YzM0MjE3YTMwZjFjNjZlOTYyNGMyMSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfY2NmOGE3YmQ4NzJiNGQ0M2JkMTg4ZmUxYjgwODI2YzEuYmluZFBvcHVwKHBvcHVwX2YzMjIzOWIyNjQ1OTQ2ZTQ5ZTlhOTQ0ZDI0NjRkNjg1KQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9hOTYxNWU5YzI1YWI0YzJlYmUyMjRiOTUyZjU4MTk1MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjY2Mjc0MzksIC03OS4zMjE1NThdLAogICAgICAgICAgICAgICAgeyJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwgImNvbG9yIjogIiM4MDAwZmYiLCAiZGFzaEFycmF5IjogbnVsbCwgImRhc2hPZmZzZXQiOiBudWxsLCAiZmlsbCI6IHRydWUsICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsICJmaWxsT3BhY2l0eSI6IDAuNywgImZpbGxSdWxlIjogImV2ZW5vZGQiLCAibGluZUNhcCI6ICJyb3VuZCIsICJsaW5lSm9pbiI6ICJyb3VuZCIsICJvcGFjaXR5IjogMS4wLCAicmFkaXVzIjogNSwgInN0cm9rZSI6IHRydWUsICJ3ZWlnaHQiOiAzfQogICAgICAgICAgICApLmFkZFRvKG1hcF9jZGMzMDg0ZGMzZTA0ZTU1OGZkMWVhMTMzMzNlMGQ4NSk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgcG9wdXBfYjc4ZWRlZTFiMjVlNDI0Yzk1MmE2NTVkZTk4YWJkOGYgPSBMLnBvcHVwKHsibWF4V2lkdGgiOiAiMTAwJSJ9KTsKCiAgICAgICAgCiAgICAgICAgICAgIHZhciBodG1sX2FjMGNmZDBmMTY5MDRkNjQ4OWRhNmY3MzE4Mjg3M2I5ID0gJChgPGRpdiBpZD0iaHRtbF9hYzBjZmQwZjE2OTA0ZDY0ODlkYTZmNzMxODI4NzNiOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnVzaW5lc3MgcmVwbHkgbWFpbCBQcm9jZXNzaW5nIENlbnRyZSwgU291dGggQ2VudHJhbCBMZXR0ZXIgUHJvY2Vzc2luZyBQbGFudCBUb3JvbnRvIENsdXN0ZXIgMS4wPC9kaXY+YClbMF07CiAgICAgICAgICAgIHBvcHVwX2I3OGVkZWUxYjI1ZTQyNGM5NTJhNjU1ZGU5OGFiZDhmLnNldENvbnRlbnQoaHRtbF9hYzBjZmQwZjE2OTA0ZDY0ODlkYTZmNzMxODI4NzNiOSk7CiAgICAgICAgCgogICAgICAgIGNpcmNsZV9tYXJrZXJfYTk2MTVlOWMyNWFiNGMyZWJlMjI0Yjk1MmY1ODE5NTEuYmluZFBvcHVwKHBvcHVwX2I3OGVkZWUxYjI1ZTQyNGM5NTJhNjU1ZGU5OGFiZDhmKQogICAgICAgIDsKCiAgICAgICAgCiAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl85YmZiOTRlOTNkNjI0MzVkYmIxMzJkNzY2MDg5ZDY1ZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQzLjYzNjI1NzksIC03OS40OTg1MDkwOTk5OTk5OV0sCiAgICAgICAgICAgICAgICB7ImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLCAiY29sb3IiOiAiIzgwZmZiNCIsICJkYXNoQXJyYXkiOiBudWxsLCAiZGFzaE9mZnNldCI6IG51bGwsICJmaWxsIjogdHJ1ZSwgImZpbGxDb2xvciI6ICIjODBmZmI0IiwgImZpbGxPcGFjaXR5IjogMC43LCAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsICJsaW5lQ2FwIjogInJvdW5kIiwgImxpbmVKb2luIjogInJvdW5kIiwgIm9wYWNpdHkiOiAxLjAsICJyYWRpdXMiOiA1LCAic3Ryb2tlIjogdHJ1ZSwgIndlaWdodCI6IDN9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2NkYzMwODRkYzNlMDRlNTU4ZmQxZWExMzMzM2UwZDg1KTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBwb3B1cF81OTA2MWM4ZjI5ZGE0OTgyOTM0NDZlMjBmOTAyNDE1YSA9IEwucG9wdXAoeyJtYXhXaWR0aCI6ICIxMDAlIn0pOwoKICAgICAgICAKICAgICAgICAgICAgdmFyIGh0bWxfYzhmZGUyOWQ3ODdkNDkzMDg1NWIxMWY2MmViOTk0YzIgPSAkKGA8ZGl2IGlkPSJodG1sX2M4ZmRlMjlkNzg3ZDQ5MzA4NTViMTFmNjJlYjk5NGMyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5PbGQgTWlsbCBTb3V0aCwgS2luZyYjMzk7cyBNaWxsIFBhcmssIFN1bm55bGVhLCBIdW1iZXIgQmF5LCBNaW1pY28gTkUsIFRoZSBRdWVlbnN3YXkgRWFzdCwgUm95YWwgWW9yayBTb3V0aCBFYXN0LCBLaW5nc3dheSBQYXJrIFNvdXRoIEVhc3QgQ2x1c3RlciAzLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfNTkwNjFjOGYyOWRhNDk4MjkzNDQ2ZTIwZjkwMjQxNWEuc2V0Q29udGVudChodG1sX2M4ZmRlMjlkNzg3ZDQ5MzA4NTViMTFmNjJlYjk5NGMyKTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl85YmZiOTRlOTNkNjI0MzVkYmIxMzJkNzY2MDg5ZDY1ZC5iaW5kUG9wdXAocG9wdXBfNTkwNjFjOGYyOWRhNDk4MjkzNDQ2ZTIwZjkwMjQxNWEpCiAgICAgICAgOwoKICAgICAgICAKICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBjMGQyZjJiODJlMDRmNDU4ZjdlYWNlZTA4YjQ5MjgxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDMuNjI4ODQwOCwgLTc5LjUyMDk5OTQwMDAwMDAxXSwKICAgICAgICAgICAgICAgIHsiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsICJjb2xvciI6ICIjODAwMGZmIiwgImRhc2hBcnJheSI6IG51bGwsICJkYXNoT2Zmc2V0IjogbnVsbCwgImZpbGwiOiB0cnVlLCAiZmlsbENvbG9yIjogIiM4MDAwZmYiLCAiZmlsbE9wYWNpdHkiOiAwLjcsICJmaWxsUnVsZSI6ICJldmVub2RkIiwgImxpbmVDYXAiOiAicm91bmQiLCAibGluZUpvaW4iOiAicm91bmQiLCAib3BhY2l0eSI6IDEuMCwgInJhZGl1cyI6IDUsICJzdHJva2UiOiB0cnVlLCAid2VpZ2h0IjogM30KICAgICAgICAgICAgKS5hZGRUbyhtYXBfY2RjMzA4NGRjM2UwNGU1NThmZDFlYTEzMzMzZTBkODUpOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIHBvcHVwX2VhZDJlMzA5YmIzMTQ5MzA5ZWVmZTU4MjIxMzMzY2FiID0gTC5wb3B1cCh7Im1heFdpZHRoIjogIjEwMCUifSk7CgogICAgICAgIAogICAgICAgICAgICB2YXIgaHRtbF9iYmQ0ZTllZjc1MTk0NDU3OGYyNDhlM2VlYTM3OTg2OCA9ICQoYDxkaXYgaWQ9Imh0bWxfYmJkNGU5ZWY3NTE5NDQ1NzhmMjQ4ZTNlZWEzNzk4NjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPk1pbWljbyBOVywgVGhlIFF1ZWVuc3dheSBXZXN0LCBTb3V0aCBvZiBCbG9vciwgS2luZ3N3YXkgUGFyayBTb3V0aCBXZXN0LCBSb3lhbCBZb3JrIFNvdXRoIFdlc3QgQ2x1c3RlciAxLjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgcG9wdXBfZWFkMmUzMDliYjMxNDkzMDllZWZlNTgyMjEzMzNjYWIuc2V0Q29udGVudChodG1sX2JiZDRlOWVmNzUxOTQ0NTc4ZjI0OGUzZWVhMzc5ODY4KTsKICAgICAgICAKCiAgICAgICAgY2lyY2xlX21hcmtlcl8wYzBkMmYyYjgyZTA0ZjQ1OGY3ZWFjZWUwOGI0OTI4MS5iaW5kUG9wdXAocG9wdXBfZWFkMmUzMDliYjMxNDkzMDllZWZlNTgyMjEzMzNjYWIpCiAgICAgICAgOwoKICAgICAgICAKICAgIAo8L3NjcmlwdD4= onload=\"this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
2773      ],
2774      "text/plain": [
2775       "<folium.folium.Map at 0x1a065958388>"
2776      ]
2777     },
2778     "execution_count": 115,
2779     "metadata": {},
2780     "output_type": "execute_result"
2781    }
2782   ],
2783   "source": [
2784    "import matplotlib.cm as cm\n",
2785    "import matplotlib.colors as colors\n",
2786    "\n",
2787    "# create map\n",
2788    "map_clusters = folium.Map(location=[latitude, longitude], zoom_start=11)\n",
2789    "\n",
2790    "# set color scheme for the clusters\n",
2791    "x = np.arange(kclusters)\n",
2792    "ys = [i + x + (i*x)**2 for i in range(kclusters)]\n",
2793    "colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))\n",
2794    "rainbow = [colors.rgb2hex(i) for i in colors_array]\n",
2795    "\n",
2796    "toronto_merged_nonan = toronto_merged.dropna(subset=['Cluster Labels'])\n",
2797    "\n",
2798    "# add markers to the map\n",
2799    "markers_colors = []\n",
2800    "for lat, lon, poi, cluster in zip(toronto_merged_nonan['Latitude'], toronto_merged_nonan['Longitude'], toronto_merged_nonan['Neighbourhood'], toronto_merged_nonan['Cluster Labels']):\n",
2801    "    label = folium.Popup(str(poi) + ' Cluster ' + str(cluster), parse_html=True)\n",
2802    "    folium.CircleMarker(\n",
2803    "        [lat, lon],\n",
2804    "        radius=5,\n",
2805    "        popup=label,\n",
2806    "        color=rainbow[int(cluster-1)],\n",
2807    "        fill=True,\n",
2808    "        fill_color=rainbow[int(cluster-1)],\n",
2809    "        fill_opacity=0.7).add_to(map_clusters)\n",
2810    "       \n",
2811    "map_clusters"
2812   ]
2813  },
2814  {
2815   "cell_type": "markdown",
2816   "metadata": {},
2817   "source": [
2818    "Cluster 1"
2819   ]
2820  },
2821  {
2822   "cell_type": "code",
2823   "execution_count": 116,
2824   "metadata": {},
2825   "outputs": [
2826    {
2827     "data": {
2828      "text/html": [
2829       "<div>\n",
2830       "<style scoped>\n",
2831       "    .dataframe tbody tr th:only-of-type {\n",
2832       "        vertical-align: middle;\n",
2833       "    }\n",
2834       "\n",
2835       "    .dataframe tbody tr th {\n",
2836       "        vertical-align: top;\n",
2837       "    }\n",
2838       "\n",
2839       "    .dataframe thead th {\n",
2840       "        text-align: right;\n",
2841       "    }\n",
2842       "</style>\n",
2843       "<table border=\"1\" class=\"dataframe\">\n",
2844       "  <thead>\n",
2845       "    <tr style=\"text-align: right;\">\n",
2846       "      <th></th>\n",
2847       "      <th>Borough</th>\n",
2848       "      <th>Cluster Labels</th>\n",
2849       "      <th>1st Most Common Venue</th>\n",
2850       "      <th>2nd Most Common Venue</th>\n",
2851       "      <th>3rd Most Common Venue</th>\n",
2852       "      <th>4th Most Common Venue</th>\n",
2853       "      <th>5th Most Common Venue</th>\n",
2854       "      <th>6th Most Common Venue</th>\n",
2855       "      <th>7th Most Common Venue</th>\n",
2856       "      <th>8th Most Common Venue</th>\n",
2857       "      <th>9th Most Common Venue</th>\n",
2858       "      <th>10th Most Common Venue</th>\n",
2859       "    </tr>\n",
2860       "  </thead>\n",
2861       "  <tbody>\n",
2862       "    <tr>\n",
2863       "      <th>0</th>\n",
2864       "      <td>North York</td>\n",
2865       "      <td>0.0</td>\n",
2866       "      <td>Park</td>\n",
2867       "      <td>Food &amp; Drink Shop</td>\n",
2868       "      <td>Yoga Studio</td>\n",
2869       "      <td>Donut Shop</td>\n",
2870       "      <td>Diner</td>\n",
2871       "      <td>Discount Store</td>\n",
2872       "      <td>Distribution Center</td>\n",
2873       "      <td>Dog Run</td>\n",
2874       "      <td>Doner Restaurant</td>\n",
2875       "      <td>Drugstore</td>\n",
2876       "    </tr>\n",
2877       "    <tr>\n",
2878       "      <th>21</th>\n",
2879       "      <td>York</td>\n",
2880       "      <td>0.0</td>\n",
2881       "      <td>Park</td>\n",
2882       "      <td>Women's Store</td>\n",
2883       "      <td>Pool</td>\n",
2884       "      <td>Yoga Studio</td>\n",
2885       "      <td>Doner Restaurant</td>\n",
2886       "      <td>Dim Sum Restaurant</td>\n",
2887       "      <td>Diner</td>\n",
2888       "      <td>Discount Store</td>\n",
2889       "      <td>Distribution Center</td>\n",
2890       "      <td>Dog Run</td>\n",
2891       "    </tr>\n",
2892       "    <tr>\n",
2893       "      <th>35</th>\n",
2894       "      <td>East York</td>\n",
2895       "      <td>0.0</td>\n",
2896       "      <td>Park</td>\n",
2897       "      <td>Convenience Store</td>\n",
2898       "      <td>Yoga Studio</td>\n",
2899       "      <td>Donut Shop</td>\n",
2900       "      <td>Diner</td>\n",
2901       "      <td>Discount Store</td>\n",
2902       "      <td>Distribution Center</td>\n",
2903       "      <td>Dog Run</td>\n",
2904       "      <td>Doner Restaurant</td>\n",
2905       "      <td>Dumpling Restaurant</td>\n",
2906       "    </tr>\n",
2907       "    <tr>\n",
2908       "      <th>52</th>\n",
2909       "      <td>North York</td>\n",
2910       "      <td>0.0</td>\n",
2911       "      <td>Park</td>\n",
2912       "      <td>Yoga Studio</td>\n",
2913       "      <td>Donut Shop</td>\n",
2914       "      <td>Dim Sum Restaurant</td>\n",
2915       "      <td>Diner</td>\n",
2916       "      <td>Discount Store</td>\n",
2917       "      <td>Distribution Center</td>\n",
2918       "      <td>Dog Run</td>\n",
2919       "      <td>Doner Restaurant</td>\n",
2920       "      <td>Drugstore</td>\n",
2921       "    </tr>\n",
2922       "    <tr>\n",
2923       "      <th>64</th>\n",
2924       "      <td>York</td>\n",
2925       "      <td>0.0</td>\n",
2926       "      <td>Park</td>\n",
2927       "      <td>Convenience Store</td>\n",
2928       "      <td>Yoga Studio</td>\n",
2929       "      <td>Donut Shop</td>\n",
2930       "      <td>Diner</td>\n",
2931       "      <td>Discount Store</td>\n",
2932       "      <td>Distribution Center</td>\n",
2933       "      <td>Dog Run</td>\n",
2934       "      <td>Doner Restaurant</td>\n",
2935       "      <td>Dumpling Restaurant</td>\n",
2936       "    </tr>\n",
2937       "    <tr>\n",
2938       "      <th>66</th>\n",
2939       "      <td>North York</td>\n",
2940       "      <td>0.0</td>\n",
2941       "      <td>Park</td>\n",
2942       "      <td>Construction &amp; Landscaping</td>\n",
2943       "      <td>Convenience Store</td>\n",
2944       "      <td>Yoga Studio</td>\n",
2945       "      <td>Donut Shop</td>\n",
2946       "      <td>Diner</td>\n",
2947       "      <td>Discount Store</td>\n",
2948       "      <td>Distribution Center</td>\n",
2949       "      <td>Dog Run</td>\n",
2950       "      <td>Doner Restaurant</td>\n",
2951       "    </tr>\n",
2952       "    <tr>\n",
2953       "      <th>85</th>\n",
2954       "      <td>Scarborough</td>\n",
2955       "      <td>0.0</td>\n",
2956       "      <td>Park</td>\n",
2957       "      <td>Playground</td>\n",
2958       "      <td>Coffee Shop</td>\n",
2959       "      <td>Yoga Studio</td>\n",
2960       "      <td>Doner Restaurant</td>\n",
2961       "      <td>Dim Sum Restaurant</td>\n",
2962       "      <td>Diner</td>\n",
2963       "      <td>Discount Store</td>\n",
2964       "      <td>Distribution Center</td>\n",
2965       "      <td>Dog Run</td>\n",
2966       "    </tr>\n",
2967       "    <tr>\n",
2968       "      <th>91</th>\n",
2969       "      <td>Downtown Toronto</td>\n",
2970       "      <td>0.0</td>\n",
2971       "      <td>Park</td>\n",
2972       "      <td>Trail</td>\n",
2973       "      <td>Playground</td>\n",
2974       "      <td>Yoga Studio</td>\n",
2975       "      <td>Dessert Shop</td>\n",
2976       "      <td>Dim Sum Restaurant</td>\n",
2977       "      <td>Diner</td>\n",
2978       "      <td>Discount Store</td>\n",
2979       "      <td>Distribution Center</td>\n",
2980       "      <td>Dog Run</td>\n",
2981       "    </tr>\n",
2982       "  </tbody>\n",
2983       "</table>\n",
2984       "</div>"
2985      ],
2986      "text/plain": [
2987       "             Borough  Cluster Labels 1st Most Common Venue  \\\n",
2988       "0         North York             0.0                  Park   \n",
2989       "21              York             0.0                  Park   \n",
2990       "35         East York             0.0                  Park   \n",
2991       "52        North York             0.0                  Park   \n",
2992       "64              York             0.0                  Park   \n",
2993       "66        North York             0.0                  Park   \n",
2994       "85       Scarborough             0.0                  Park   \n",
2995       "91  Downtown Toronto             0.0                  Park   \n",
2996       "\n",
2997       "         2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue  \\\n",
2998       "0            Food & Drink Shop           Yoga Studio            Donut Shop   \n",
2999       "21               Women's Store                  Pool           Yoga Studio   \n",
3000       "35           Convenience Store           Yoga Studio            Donut Shop   \n",
3001       "52                 Yoga Studio            Donut Shop    Dim Sum Restaurant   \n",
3002       "64           Convenience Store           Yoga Studio            Donut Shop   \n",
3003       "66  Construction & Landscaping     Convenience Store           Yoga Studio   \n",
3004       "85                  Playground           Coffee Shop           Yoga Studio   \n",
3005       "91                       Trail            Playground           Yoga Studio   \n",
3006       "\n",
3007       "   5th Most Common Venue 6th Most Common Venue 7th Most Common Venue  \\\n",
3008       "0                  Diner        Discount Store   Distribution Center   \n",
3009       "21      Doner Restaurant    Dim Sum Restaurant                 Diner   \n",
3010       "35                 Diner        Discount Store   Distribution Center   \n",
3011       "52                 Diner        Discount Store   Distribution Center   \n",
3012       "64                 Diner        Discount Store   Distribution Center   \n",
3013       "66            Donut Shop                 Diner        Discount Store   \n",
3014       "85      Doner Restaurant    Dim Sum Restaurant                 Diner   \n",
3015       "91          Dessert Shop    Dim Sum Restaurant                 Diner   \n",
3016       "\n",
3017       "   8th Most Common Venue 9th Most Common Venue 10th Most Common Venue  \n",
3018       "0                Dog Run      Doner Restaurant              Drugstore  \n",
3019       "21        Discount Store   Distribution Center                Dog Run  \n",
3020       "35               Dog Run      Doner Restaurant    Dumpling Restaurant  \n",
3021       "52               Dog Run      Doner Restaurant              Drugstore  \n",
3022       "64               Dog Run      Doner Restaurant    Dumpling Restaurant  \n",
3023       "66   Distribution Center               Dog Run       Doner Restaurant  \n",
3024       "85        Discount Store   Distribution Center                Dog Run  \n",
3025       "91        Discount Store   Distribution Center                Dog Run  "
3026      ]
3027     },
3028     "execution_count": 116,
3029     "metadata": {},
3030     "output_type": "execute_result"
3031    }
3032   ],
3033   "source": [
3034    "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 0, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3035   ]
3036  },
3037  {
3038   "cell_type": "markdown",
3039   "metadata": {},
3040   "source": [
3041    "Cluster 2"
3042   ]
3043  },
3044  {
3045   "cell_type": "code",
3046   "execution_count": 117,
3047   "metadata": {},
3048   "outputs": [
3049    {
3050     "data": {
3051      "text/html": [
3052       "<div>\n",
3053       "<style scoped>\n",
3054       "    .dataframe tbody tr th:only-of-type {\n",
3055       "        vertical-align: middle;\n",
3056       "    }\n",
3057       "\n",
3058       "    .dataframe tbody tr th {\n",
3059       "        vertical-align: top;\n",
3060       "    }\n",
3061       "\n",
3062       "    .dataframe thead th {\n",
3063       "        text-align: right;\n",
3064       "    }\n",
3065       "</style>\n",
3066       "<table border=\"1\" class=\"dataframe\">\n",
3067       "  <thead>\n",
3068       "    <tr style=\"text-align: right;\">\n",
3069       "      <th></th>\n",
3070       "      <th>Borough</th>\n",
3071       "      <th>Cluster Labels</th>\n",
3072       "      <th>1st Most Common Venue</th>\n",
3073       "      <th>2nd Most Common Venue</th>\n",
3074       "      <th>3rd Most Common Venue</th>\n",
3075       "      <th>4th Most Common Venue</th>\n",
3076       "      <th>5th Most Common Venue</th>\n",
3077       "      <th>6th Most Common Venue</th>\n",
3078       "      <th>7th Most Common Venue</th>\n",
3079       "      <th>8th Most Common Venue</th>\n",
3080       "      <th>9th Most Common Venue</th>\n",
3081       "      <th>10th Most Common Venue</th>\n",
3082       "    </tr>\n",
3083       "  </thead>\n",
3084       "  <tbody>\n",
3085       "    <tr>\n",
3086       "      <th>1</th>\n",
3087       "      <td>North York</td>\n",
3088       "      <td>1.0</td>\n",
3089       "      <td>Hockey Arena</td>\n",
3090       "      <td>Pizza Place</td>\n",
3091       "      <td>Coffee Shop</td>\n",
3092       "      <td>Portuguese Restaurant</td>\n",
3093       "      <td>Yoga Studio</td>\n",
3094       "      <td>Dim Sum Restaurant</td>\n",
3095       "      <td>Diner</td>\n",
3096       "      <td>Discount Store</td>\n",
3097       "      <td>Distribution Center</td>\n",
3098       "      <td>Dog Run</td>\n",
3099       "    </tr>\n",
3100       "    <tr>\n",
3101       "      <th>2</th>\n",
3102       "      <td>Downtown Toronto</td>\n",
3103       "      <td>1.0</td>\n",
3104       "      <td>Coffee Shop</td>\n",
3105       "      <td>Bakery</td>\n",
3106       "      <td>Pub</td>\n",
3107       "      <td>Park</td>\n",
3108       "      <td>Breakfast Spot</td>\n",
3109       "      <td>Café</td>\n",
3110       "      <td>Theater</td>\n",
3111       "      <td>Yoga Studio</td>\n",
3112       "      <td>Mexican Restaurant</td>\n",
3113       "      <td>Shoe Store</td>\n",
3114       "    </tr>\n",
3115       "    <tr>\n",
3116       "      <th>3</th>\n",
3117       "      <td>North York</td>\n",
3118       "      <td>1.0</td>\n",
3119       "      <td>Clothing Store</td>\n",
3120       "      <td>Accessories Store</td>\n",
3121       "      <td>Coffee Shop</td>\n",
3122       "      <td>Boutique</td>\n",
3123       "      <td>Miscellaneous Shop</td>\n",
3124       "      <td>Event Space</td>\n",
3125       "      <td>Furniture / Home Store</td>\n",
3126       "      <td>Women's Store</td>\n",
3127       "      <td>Vietnamese Restaurant</td>\n",
3128       "      <td>Convenience Store</td>\n",
3129       "    </tr>\n",
3130       "    <tr>\n",
3131       "      <th>4</th>\n",
3132       "      <td>Downtown Toronto</td>\n",
3133       "      <td>1.0</td>\n",
3134       "      <td>Coffee Shop</td>\n",
3135       "      <td>Diner</td>\n",
3136       "      <td>Yoga Studio</td>\n",
3137       "      <td>Bar</td>\n",
3138       "      <td>Beer Bar</td>\n",
3139       "      <td>Smoothie Shop</td>\n",
3140       "      <td>Sandwich Place</td>\n",
3141       "      <td>Burrito Place</td>\n",
3142       "      <td>Café</td>\n",
3143       "      <td>Park</td>\n",
3144       "    </tr>\n",
3145       "    <tr>\n",
3146       "      <th>6</th>\n",
3147       "      <td>Scarborough</td>\n",
3148       "      <td>1.0</td>\n",
3149       "      <td>Print Shop</td>\n",
3150       "      <td>Fast Food Restaurant</td>\n",
3151       "      <td>Yoga Studio</td>\n",
3152       "      <td>Dim Sum Restaurant</td>\n",
3153       "      <td>Diner</td>\n",
3154       "      <td>Discount Store</td>\n",
3155       "      <td>Distribution Center</td>\n",
3156       "      <td>Dog Run</td>\n",
3157       "      <td>Doner Restaurant</td>\n",
3158       "      <td>Donut Shop</td>\n",
3159       "    </tr>\n",
3160       "    <tr>\n",
3161       "      <th>...</th>\n",
3162       "      <td>...</td>\n",
3163       "      <td>...</td>\n",
3164       "      <td>...</td>\n",
3165       "      <td>...</td>\n",
3166       "      <td>...</td>\n",
3167       "      <td>...</td>\n",
3168       "      <td>...</td>\n",
3169       "      <td>...</td>\n",
3170       "      <td>...</td>\n",
3171       "      <td>...</td>\n",
3172       "      <td>...</td>\n",
3173       "      <td>...</td>\n",
3174       "    </tr>\n",
3175       "    <tr>\n",
3176       "      <th>97</th>\n",
3177       "      <td>Downtown Toronto</td>\n",
3178       "      <td>1.0</td>\n",
3179       "      <td>Coffee Shop</td>\n",
3180       "      <td>Café</td>\n",
3181       "      <td>Hotel</td>\n",
3182       "      <td>Restaurant</td>\n",
3183       "      <td>Gym</td>\n",
3184       "      <td>Japanese Restaurant</td>\n",
3185       "      <td>American Restaurant</td>\n",
3186       "      <td>Steakhouse</td>\n",
3187       "      <td>Asian Restaurant</td>\n",
3188       "      <td>Seafood Restaurant</td>\n",
3189       "    </tr>\n",
3190       "    <tr>\n",
3191       "      <th>98</th>\n",
3192       "      <td>Etobicoke</td>\n",
3193       "      <td>1.0</td>\n",
3194       "      <td>River</td>\n",
3195       "      <td>Doner Restaurant</td>\n",
3196       "      <td>Dessert Shop</td>\n",
3197       "      <td>Dim Sum Restaurant</td>\n",
3198       "      <td>Diner</td>\n",
3199       "      <td>Discount Store</td>\n",
3200       "      <td>Distribution Center</td>\n",
3201       "      <td>Dog Run</td>\n",
3202       "      <td>Yoga Studio</td>\n",
3203       "      <td>Department Store</td>\n",
3204       "    </tr>\n",
3205       "    <tr>\n",
3206       "      <th>99</th>\n",
3207       "      <td>Downtown Toronto</td>\n",
3208       "      <td>1.0</td>\n",
3209       "      <td>Coffee Shop</td>\n",
3210       "      <td>Sushi Restaurant</td>\n",
3211       "      <td>Japanese Restaurant</td>\n",
3212       "      <td>Gay Bar</td>\n",
3213       "      <td>Restaurant</td>\n",
3214       "      <td>Yoga Studio</td>\n",
3215       "      <td>Bubble Tea Shop</td>\n",
3216       "      <td>Dance Studio</td>\n",
3217       "      <td>Mediterranean Restaurant</td>\n",
3218       "      <td>Men's Store</td>\n",
3219       "    </tr>\n",
3220       "    <tr>\n",
3221       "      <th>100</th>\n",
3222       "      <td>East Toronto</td>\n",
3223       "      <td>1.0</td>\n",
3224       "      <td>Light Rail Station</td>\n",
3225       "      <td>Yoga Studio</td>\n",
3226       "      <td>Auto Workshop</td>\n",
3227       "      <td>Smoke Shop</td>\n",
3228       "      <td>Brewery</td>\n",
3229       "      <td>Spa</td>\n",
3230       "      <td>Farmers Market</td>\n",
3231       "      <td>Fast Food Restaurant</td>\n",
3232       "      <td>Burrito Place</td>\n",
3233       "      <td>Restaurant</td>\n",
3234       "    </tr>\n",
3235       "    <tr>\n",
3236       "      <th>102</th>\n",
3237       "      <td>Etobicoke</td>\n",
3238       "      <td>1.0</td>\n",
3239       "      <td>Grocery Store</td>\n",
3240       "      <td>Tanning Salon</td>\n",
3241       "      <td>Convenience Store</td>\n",
3242       "      <td>Discount Store</td>\n",
3243       "      <td>Burrito Place</td>\n",
3244       "      <td>Burger Joint</td>\n",
3245       "      <td>Sandwich Place</td>\n",
3246       "      <td>Kids Store</td>\n",
3247       "      <td>Supplement Shop</td>\n",
3248       "      <td>Bakery</td>\n",
3249       "    </tr>\n",
3250       "  </tbody>\n",
3251       "</table>\n",
3252       "<p>87 rows × 12 columns</p>\n",
3253       "</div>"
3254      ],
3255      "text/plain": [
3256       "              Borough  Cluster Labels 1st Most Common Venue  \\\n",
3257       "1          North York             1.0          Hockey Arena   \n",
3258       "2    Downtown Toronto             1.0           Coffee Shop   \n",
3259       "3          North York             1.0        Clothing Store   \n",
3260       "4    Downtown Toronto             1.0           Coffee Shop   \n",
3261       "6         Scarborough             1.0            Print Shop   \n",
3262       "..                ...             ...                   ...   \n",
3263       "97   Downtown Toronto             1.0           Coffee Shop   \n",
3264       "98          Etobicoke             1.0                 River   \n",
3265       "99   Downtown Toronto             1.0           Coffee Shop   \n",
3266       "100      East Toronto             1.0    Light Rail Station   \n",
3267       "102         Etobicoke             1.0         Grocery Store   \n",
3268       "\n",
3269       "    2nd Most Common Venue 3rd Most Common Venue  4th Most Common Venue  \\\n",
3270       "1             Pizza Place           Coffee Shop  Portuguese Restaurant   \n",
3271       "2                  Bakery                   Pub                   Park   \n",
3272       "3       Accessories Store           Coffee Shop               Boutique   \n",
3273       "4                   Diner           Yoga Studio                    Bar   \n",
3274       "6    Fast Food Restaurant           Yoga Studio     Dim Sum Restaurant   \n",
3275       "..                    ...                   ...                    ...   \n",
3276       "97                   Café                 Hotel             Restaurant   \n",
3277       "98       Doner Restaurant          Dessert Shop     Dim Sum Restaurant   \n",
3278       "99       Sushi Restaurant   Japanese Restaurant                Gay Bar   \n",
3279       "100           Yoga Studio         Auto Workshop             Smoke Shop   \n",
3280       "102         Tanning Salon     Convenience Store         Discount Store   \n",
3281       "\n",
3282       "    5th Most Common Venue 6th Most Common Venue   7th Most Common Venue  \\\n",
3283       "1             Yoga Studio    Dim Sum Restaurant                   Diner   \n",
3284       "2          Breakfast Spot                  Café                 Theater   \n",
3285       "3      Miscellaneous Shop           Event Space  Furniture / Home Store   \n",
3286       "4                Beer Bar         Smoothie Shop          Sandwich Place   \n",
3287       "6                   Diner        Discount Store     Distribution Center   \n",
3288       "..                    ...                   ...                     ...   \n",
3289       "97                    Gym   Japanese Restaurant     American Restaurant   \n",
3290       "98                  Diner        Discount Store     Distribution Center   \n",
3291       "99             Restaurant           Yoga Studio         Bubble Tea Shop   \n",
3292       "100               Brewery                   Spa          Farmers Market   \n",
3293       "102         Burrito Place          Burger Joint          Sandwich Place   \n",
3294       "\n",
3295       "    8th Most Common Venue     9th Most Common Venue 10th Most Common Venue  \n",
3296       "1          Discount Store       Distribution Center                Dog Run  \n",
3297       "2             Yoga Studio        Mexican Restaurant             Shoe Store  \n",
3298       "3           Women's Store     Vietnamese Restaurant      Convenience Store  \n",
3299       "4           Burrito Place                      Café                   Park  \n",
3300       "6                 Dog Run          Doner Restaurant             Donut Shop  \n",
3301       "..                    ...                       ...                    ...  \n",
3302       "97             Steakhouse          Asian Restaurant     Seafood Restaurant  \n",
3303       "98                Dog Run               Yoga Studio       Department Store  \n",
3304       "99           Dance Studio  Mediterranean Restaurant            Men's Store  \n",
3305       "100  Fast Food Restaurant             Burrito Place             Restaurant  \n",
3306       "102            Kids Store           Supplement Shop                 Bakery  \n",
3307       "\n",
3308       "[87 rows x 12 columns]"
3309      ]
3310     },
3311     "execution_count": 117,
3312     "metadata": {},
3313     "output_type": "execute_result"
3314    }
3315   ],
3316   "source": [
3317    "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 1, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3318   ]
3319  },
3320  {
3321   "cell_type": "markdown",
3322   "metadata": {},
3323   "source": [
3324    "Cluster 3"
3325   ]
3326  },
3327  {
3328   "cell_type": "code",
3329   "execution_count": 118,
3330   "metadata": {},
3331   "outputs": [
3332    {
3333     "data": {
3334      "text/html": [
3335       "<div>\n",
3336       "<style scoped>\n",
3337       "    .dataframe tbody tr th:only-of-type {\n",
3338       "        vertical-align: middle;\n",
3339       "    }\n",
3340       "\n",
3341       "    .dataframe tbody tr th {\n",
3342       "        vertical-align: top;\n",
3343       "    }\n",
3344       "\n",
3345       "    .dataframe thead th {\n",
3346       "        text-align: right;\n",
3347       "    }\n",
3348       "</style>\n",
3349       "<table border=\"1\" class=\"dataframe\">\n",
3350       "  <thead>\n",
3351       "    <tr style=\"text-align: right;\">\n",
3352       "      <th></th>\n",
3353       "      <th>Borough</th>\n",
3354       "      <th>Cluster Labels</th>\n",
3355       "      <th>1st Most Common Venue</th>\n",
3356       "      <th>2nd Most Common Venue</th>\n",
3357       "      <th>3rd Most Common Venue</th>\n",
3358       "      <th>4th Most Common Venue</th>\n",
3359       "      <th>5th Most Common Venue</th>\n",
3360       "      <th>6th Most Common Venue</th>\n",
3361       "      <th>7th Most Common Venue</th>\n",
3362       "      <th>8th Most Common Venue</th>\n",
3363       "      <th>9th Most Common Venue</th>\n",
3364       "      <th>10th Most Common Venue</th>\n",
3365       "    </tr>\n",
3366       "  </thead>\n",
3367       "  <tbody>\n",
3368       "    <tr>\n",
3369       "      <th>32</th>\n",
3370       "      <td>Scarborough</td>\n",
3371       "      <td>2.0</td>\n",
3372       "      <td>Pizza Place</td>\n",
3373       "      <td>Playground</td>\n",
3374       "      <td>Doner Restaurant</td>\n",
3375       "      <td>Dessert Shop</td>\n",
3376       "      <td>Dim Sum Restaurant</td>\n",
3377       "      <td>Diner</td>\n",
3378       "      <td>Discount Store</td>\n",
3379       "      <td>Distribution Center</td>\n",
3380       "      <td>Dog Run</td>\n",
3381       "      <td>Donut Shop</td>\n",
3382       "    </tr>\n",
3383       "    <tr>\n",
3384       "      <th>50</th>\n",
3385       "      <td>North York</td>\n",
3386       "      <td>2.0</td>\n",
3387       "      <td>Pizza Place</td>\n",
3388       "      <td>Department Store</td>\n",
3389       "      <td>Event Space</td>\n",
3390       "      <td>Ethiopian Restaurant</td>\n",
3391       "      <td>Electronics Store</td>\n",
3392       "      <td>Eastern European Restaurant</td>\n",
3393       "      <td>Dumpling Restaurant</td>\n",
3394       "      <td>Drugstore</td>\n",
3395       "      <td>Donut Shop</td>\n",
3396       "      <td>Doner Restaurant</td>\n",
3397       "    </tr>\n",
3398       "  </tbody>\n",
3399       "</table>\n",
3400       "</div>"
3401      ],
3402      "text/plain": [
3403       "        Borough  Cluster Labels 1st Most Common Venue 2nd Most Common Venue  \\\n",
3404       "32  Scarborough             2.0           Pizza Place            Playground   \n",
3405       "50   North York             2.0           Pizza Place      Department Store   \n",
3406       "\n",
3407       "   3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue  \\\n",
3408       "32      Doner Restaurant          Dessert Shop    Dim Sum Restaurant   \n",
3409       "50           Event Space  Ethiopian Restaurant     Electronics Store   \n",
3410       "\n",
3411       "          6th Most Common Venue 7th Most Common Venue 8th Most Common Venue  \\\n",
3412       "32                        Diner        Discount Store   Distribution Center   \n",
3413       "50  Eastern European Restaurant   Dumpling Restaurant             Drugstore   \n",
3414       "\n",
3415       "   9th Most Common Venue 10th Most Common Venue  \n",
3416       "32               Dog Run             Donut Shop  \n",
3417       "50            Donut Shop       Doner Restaurant  "
3418      ]
3419     },
3420     "execution_count": 118,
3421     "metadata": {},
3422     "output_type": "execute_result"
3423    }
3424   ],
3425   "source": [
3426    "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 2, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3427   ]
3428  },
3429  {
3430   "cell_type": "markdown",
3431   "metadata": {},
3432   "source": [
3433    "Cluster 4"
3434   ]
3435  },
3436  {
3437   "cell_type": "code",
3438   "execution_count": 119,
3439   "metadata": {},
3440   "outputs": [
3441    {
3442     "data": {
3443      "text/html": [
3444       "<div>\n",
3445       "<style scoped>\n",
3446       "    .dataframe tbody tr th:only-of-type {\n",
3447       "        vertical-align: middle;\n",
3448       "    }\n",
3449       "\n",
3450       "    .dataframe tbody tr th {\n",
3451       "        vertical-align: top;\n",
3452       "    }\n",
3453       "\n",
3454       "    .dataframe thead th {\n",
3455       "        text-align: right;\n",
3456       "    }\n",
3457       "</style>\n",
3458       "<table border=\"1\" class=\"dataframe\">\n",
3459       "  <thead>\n",
3460       "    <tr style=\"text-align: right;\">\n",
3461       "      <th></th>\n",
3462       "      <th>Borough</th>\n",
3463       "      <th>Cluster Labels</th>\n",
3464       "      <th>1st Most Common Venue</th>\n",
3465       "      <th>2nd Most Common Venue</th>\n",
3466       "      <th>3rd Most Common Venue</th>\n",
3467       "      <th>4th Most Common Venue</th>\n",
3468       "      <th>5th Most Common Venue</th>\n",
3469       "      <th>6th Most Common Venue</th>\n",
3470       "      <th>7th Most Common Venue</th>\n",
3471       "      <th>8th Most Common Venue</th>\n",
3472       "      <th>9th Most Common Venue</th>\n",
3473       "      <th>10th Most Common Venue</th>\n",
3474       "    </tr>\n",
3475       "  </thead>\n",
3476       "  <tbody>\n",
3477       "    <tr>\n",
3478       "      <th>57</th>\n",
3479       "      <td>North York</td>\n",
3480       "      <td>3.0</td>\n",
3481       "      <td>Fabric Shop</td>\n",
3482       "      <td>Baseball Field</td>\n",
3483       "      <td>Yoga Studio</td>\n",
3484       "      <td>Donut Shop</td>\n",
3485       "      <td>Diner</td>\n",
3486       "      <td>Discount Store</td>\n",
3487       "      <td>Distribution Center</td>\n",
3488       "      <td>Dog Run</td>\n",
3489       "      <td>Doner Restaurant</td>\n",
3490       "      <td>Drugstore</td>\n",
3491       "    </tr>\n",
3492       "    <tr>\n",
3493       "      <th>101</th>\n",
3494       "      <td>Etobicoke</td>\n",
3495       "      <td>3.0</td>\n",
3496       "      <td>Baseball Field</td>\n",
3497       "      <td>Yoga Studio</td>\n",
3498       "      <td>Donut Shop</td>\n",
3499       "      <td>Diner</td>\n",
3500       "      <td>Discount Store</td>\n",
3501       "      <td>Distribution Center</td>\n",
3502       "      <td>Dog Run</td>\n",
3503       "      <td>Doner Restaurant</td>\n",
3504       "      <td>Drugstore</td>\n",
3505       "      <td>Farmers Market</td>\n",
3506       "    </tr>\n",
3507       "  </tbody>\n",
3508       "</table>\n",
3509       "</div>"
3510      ],
3511      "text/plain": [
3512       "        Borough  Cluster Labels 1st Most Common Venue 2nd Most Common Venue  \\\n",
3513       "57   North York             3.0           Fabric Shop        Baseball Field   \n",
3514       "101   Etobicoke             3.0        Baseball Field           Yoga Studio   \n",
3515       "\n",
3516       "    3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue  \\\n",
3517       "57            Yoga Studio            Donut Shop                 Diner   \n",
3518       "101            Donut Shop                 Diner        Discount Store   \n",
3519       "\n",
3520       "    6th Most Common Venue 7th Most Common Venue 8th Most Common Venue  \\\n",
3521       "57         Discount Store   Distribution Center               Dog Run   \n",
3522       "101   Distribution Center               Dog Run      Doner Restaurant   \n",
3523       "\n",
3524       "    9th Most Common Venue 10th Most Common Venue  \n",
3525       "57       Doner Restaurant              Drugstore  \n",
3526       "101             Drugstore         Farmers Market  "
3527      ]
3528     },
3529     "execution_count": 119,
3530     "metadata": {},
3531     "output_type": "execute_result"
3532    }
3533   ],
3534   "source": [
3535    "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 3, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3536   ]
3537  },
3538  {
3539   "cell_type": "markdown",
3540   "metadata": {},
3541   "source": [
3542    "Cluster 5"
3543   ]
3544  },
3545  {
3546   "cell_type": "code",
3547   "execution_count": 120,
3548   "metadata": {},
3549   "outputs": [
3550    {
3551     "data": {
3552      "text/html": [
3553       "<div>\n",
3554       "<style scoped>\n",
3555       "    .dataframe tbody tr th:only-of-type {\n",
3556       "        vertical-align: middle;\n",
3557       "    }\n",
3558       "\n",
3559       "    .dataframe tbody tr th {\n",
3560       "        vertical-align: top;\n",
3561       "    }\n",
3562       "\n",
3563       "    .dataframe thead th {\n",
3564       "        text-align: right;\n",
3565       "    }\n",
3566       "</style>\n",
3567       "<table border=\"1\" class=\"dataframe\">\n",
3568       "  <thead>\n",
3569       "    <tr style=\"text-align: right;\">\n",
3570       "      <th></th>\n",
3571       "      <th>Borough</th>\n",
3572       "      <th>Cluster Labels</th>\n",
3573       "      <th>1st Most Common Venue</th>\n",
3574       "      <th>2nd Most Common Venue</th>\n",
3575       "      <th>3rd Most Common Venue</th>\n",
3576       "      <th>4th Most Common Venue</th>\n",
3577       "      <th>5th Most Common Venue</th>\n",
3578       "      <th>6th Most Common Venue</th>\n",
3579       "      <th>7th Most Common Venue</th>\n",
3580       "      <th>8th Most Common Venue</th>\n",
3581       "      <th>9th Most Common Venue</th>\n",
3582       "      <th>10th Most Common Venue</th>\n",
3583       "    </tr>\n",
3584       "  </thead>\n",
3585       "  <tbody>\n",
3586       "    <tr>\n",
3587       "      <th>11</th>\n",
3588       "      <td>Etobicoke</td>\n",
3589       "      <td>4.0</td>\n",
3590       "      <td>Jewelry Store</td>\n",
3591       "      <td>Yoga Studio</td>\n",
3592       "      <td>Diner</td>\n",
3593       "      <td>Discount Store</td>\n",
3594       "      <td>Distribution Center</td>\n",
3595       "      <td>Dog Run</td>\n",
3596       "      <td>Doner Restaurant</td>\n",
3597       "      <td>Donut Shop</td>\n",
3598       "      <td>Drugstore</td>\n",
3599       "      <td>Farmers Market</td>\n",
3600       "    </tr>\n",
3601       "  </tbody>\n",
3602       "</table>\n",
3603       "</div>"
3604      ],
3605      "text/plain": [
3606       "      Borough  Cluster Labels 1st Most Common Venue 2nd Most Common Venue  \\\n",
3607       "11  Etobicoke             4.0         Jewelry Store           Yoga Studio   \n",
3608       "\n",
3609       "   3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue  \\\n",
3610       "11                 Diner        Discount Store   Distribution Center   \n",
3611       "\n",
3612       "   6th Most Common Venue 7th Most Common Venue 8th Most Common Venue  \\\n",
3613       "11               Dog Run      Doner Restaurant            Donut Shop   \n",
3614       "\n",
3615       "   9th Most Common Venue 10th Most Common Venue  \n",
3616       "11             Drugstore         Farmers Market  "
3617      ]
3618     },
3619     "execution_count": 120,
3620     "metadata": {},
3621     "output_type": "execute_result"
3622    }
3623   ],
3624   "source": [
3625    "toronto_merged_nonan.loc[toronto_merged_nonan['Cluster Labels'] == 4, toronto_merged_nonan.columns[[1] + list(range(5, toronto_merged_nonan.shape[1]))]]"
3626   ]
3627  }
3628 ],
3629 "metadata": {
3630  "kernelspec": {
3631   "display_name": "Python 3",
3632   "language": "python",
3633   "name": "python3"
3634  },
3635  "language_info": {
3636   "codemirror_mode": {
3637    "name": "ipython",
3638    "version": 3
3639   },
3640   "file_extension": ".py",
3641   "mimetype": "text/x-python",
3642   "name": "python",
3643   "nbconvert_exporter": "python",
3644   "pygments_lexer": "ipython3",
3645   "version": "3.7.6"
3646  }
3647 },
3648 "nbformat": 4,
3649 "nbformat_minor": 4
3650}