This notebook teaches you how to read satellite imagery (Sentinel-2) from Google Earth Engine together with other data, e.g. WorldClim, and aggregate them for crop yield modeling in four districts of Nepal with a RandomForest Regression and XGBoost.

Nepal data courtesy of ICIMOD.

Setup the Notebook

!pip install -q geopandas shapely scikit-learn treeinterpreter rasterio rasterstats folium 
%matplotlib inline
import os 
from os import makedirs, path as op
import matplotlib
import numpy as np
import rasterio
import geopandas as gpd
import pandas as pd
import shapely
import folium
import json
import time
import matplotlib.pyplot as plt

from sklearn import preprocessing
import xgboost as xgb
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import GridSearchCV 
from sklearn.model_selection import train_test_split
# If not on Colab you'll need install the earth-engine Python API
#!pip install earthengine-api #earth-engine Python API

import ee 
from google.colab import drive
drive.mount('/content/drive/', force_remount=True)
# your root directory for outputs is set to your google drive
# you should create a sub-folder called data under your 'Colab Notebooks'.
# An example is in https://developmentseed.org/sat-ml-training/GettingStarted#Explore-your-drive
my_root_dir = "/content/drive/My Drive/Colab Notebooks/data"
crop_data = '/content/drive/Shared drives/servir-sat-ml/data/crop_yield/'
# crop_data = '/content/drive/My Drive/SERVIR-HKH-crop-yield/crop_yield'
Mounted at /content/drive/

Wheat yield data in 2018, Nepal

The following dataset contain 145 field measurement of wheat yield data.

# reading collected wheat productivity data from excel.
wheat_2018 = pd.read_excel(op.join(crop_data, 'Wheat yield_Field_Demonstrartion_sites_2018.xlsx'))
wheat_2018 = wheat_2018.drop(columns=['Farmer'])
wheat_2018.head(1)
Unnamed: 0 Lat Long District VDC Treat Grainwt straw wt. grain moisture %, from moisture meter wheat variety 1000 Grain wt before oven dry + envelop 1000 Grain wt after oven dry + envelop Envelop wt. straw wt before overn dry +envelop straw wt. after overn dry + envelop Unnamed: 16 PH OM
0 1 28.98 80.193 Kanchanpur Suda/BDM D1 383 358.4 11.6 Banganga 57.09 53.92 NaN NaN NaN NaN 7.817228 1.688501
# only keep the columns that interest us;
wheat_2018 = wheat_2018[['Lat', 'Long', 'District','wheat variety', 'Treat', '1000 Grain wt after oven dry + envelop', 'PH', 'OM']]
# rename the column names to be more readable
wheat_2018 = wheat_2018.rename(columns={'wheat variety': 'wheat_variety', '1000 Grain wt after oven dry + envelop':'wheat_yield'})
# turn the pandas dataframe into geopandas dataframe
wheat_2018_pts = gpd.GeoDataFrame(wheat_2018, geometry=gpd.points_from_xy(wheat_2018.Long, wheat_2018.Lat))
wheat_2018_pts.head(3)
Lat Long District wheat_variety Treat wheat_yield PH OM geometry
0 28.98 80.193 Kanchanpur Banganga D1 53.92 7.817228 1.688501 POINT (80.19300 28.98000)
1 28.98 80.193 Kanchanpur Tilganga D2 50.62 7.817228 1.688501 POINT (80.19300 28.98000)
2 28.98 80.193 Kanchanpur NHS 1755 D3 40.44 7.817228 1.688501 POINT (80.19300 28.98000)
wheat_2018_pts.to_file("wheat_2018_pts.shp")

Basic stats of the wheat yield field measurements

## the field measurements located in these few districts
pd.Series(wheat_2018.District).unique()
array(['Kanchanpur', 'Kailali', 'Bardiya', 'Banke'], dtype=object)
pd.Series(wheat_2018.wheat_variety).unique()
array(['Banganga', 'Tilganga', 'NHS 1755', 'NL 971', 'Vijay', 'Aditya',
       'Local', 'Tilottama', 'Unknown', 'Indian Hybrid 2285', 'Gautam'],
      dtype=object)
# see wheat yield differences by the districts by wheat variety
only_yield = wheat_2018.drop(columns=['Long', 'Lat', 'PH', 'OM', 'geometry'])
only_yield.groupby(by=['District', 'wheat_variety']).agg({'wheat_yield': ['mean', 'min']})
wheat_yield
mean min
District wheat_variety
Banke Banganga 51.673333 47.052
Indian Hybrid 2285 38.859500 38.719
NL 971 56.288250 49.360
Unknown 48.200833 37.908
Vijay 54.399500 53.343
Bardiya Banganga 52.215875 49.540
Local 48.159500 39.768
NL 971 48.746857 46.184
Tilottama 42.915500 42.361
Unknown 45.468600 38.390
Vijay 51.320375 40.525
Kailali Aditya 48.239444 45.045
Banganga 51.846667 44.290
Local 48.487333 35.360
NL 971 48.385000 37.670
Vijay 48.782500 44.370
Kanchanpur Banganga 55.053667 52.631
Gautam 43.013500 37.003
Local 50.484500 44.880
NHS 1755 45.060000 40.440
NL 971 45.857222 35.677
Tilganga 50.620000 50.620
Vijay 49.881000 38.920
# see wheat yield differences by the districs by wheat treatment
only_yield.groupby(by=['District', 'Treat']).agg({'wheat_yield': ['mean', 'min', 'max']})
wheat_yield
mean min max
District Treat
Banke D1 52.336600 47.052 57.303
D2 49.431833 39.000 57.505
D3 49.603667 37.908 60.985
Bardiya D1 50.597000 46.184 56.418
D2 47.107600 38.390 56.181
D3 48.404067 40.346 57.723
Kailali D1 49.673750 37.670 63.030
D2 48.619375 35.360 58.530
D3 47.573667 37.770 56.790
Kanchanpur D1 48.156333 35.677 58.610
D2 50.056583 37.003 62.500
D3 47.920083 38.920 57.340

Quiz

What pattern do you see from above groupby functions over wheat yield?

Visualizing the field measurement on an interactive map

terai_bbox = gpd.GeoDataFrame(wheat_2018_pts).total_bounds
x_map=(terai_bbox[0] + terai_bbox[2])/2
y_map=(terai_bbox[1] + terai_bbox[3])/2
print(f'bouding box for Terai area is {terai_bbox}, with centroid point {x_map},{y_map}')
bouding box for Terai area is [80.165 27.999 81.648 28.986], with centroid point 80.9065,28.4925
mymap = folium.Map(location=[y_map, x_map], zoom_start=11,tiles=None)
folium.TileLayer('Stamen Terrain',name="Light Map",control=False).add_to(mymap)

tooltip = 'Click me!'
for lat, lon,  wheat_variety, wheat_yield in zip(wheat_2018.Lat, wheat_2018.Long, wheat_2018.wheat_variety, wheat_2018.wheat_yield):
  # print(lat, lon,  wheat_variety)
  folium.Marker([lat,lon], popup=f'Wheat variety: {wheat_variety}, \n Yield {wheat_yield}', tooltip=tooltip).add_to(mymap)

mymap
Make this Notebook Trusted to load map: File -> Trust Notebook<iframe src="about:blank" style="position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4xMi40Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdjZG4uZ2l0aGFjay5jb20vcHl0aG9uLXZpc3VhbGl6YXRpb24vZm9saXVtL21hc3Rlci9mb2xpdW0vdGVtcGxhdGVzL2xlYWZsZXQuYXdlc29tZS5yb3RhdGUuY3NzIi8+CiAgICA8c3R5bGU+aHRtbCwgYm9keSB7d2lkdGg6IDEwMCU7aGVpZ2h0OiAxMDAlO21hcmdpbjogMDtwYWRkaW5nOiAwO308L3N0eWxlPgogICAgPHN0eWxlPiNtYXAge3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2JvdHRvbTowO3JpZ2h0OjA7bGVmdDowO308L3N0eWxlPgogICAgCiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLAogICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgIDxzdHlsZT4jbWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjIHsKICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgICAgICAgd2lkdGg6IDEwMC4wJTsKICAgICAgICBoZWlnaHQ6IDEwMC4wJTsKICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgIHRvcDogMC4wJTsKICAgICAgICB9CiAgICA8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgPGRpdiBjbGFzcz0iZm9saXVtLW1hcCIgaWQ9Im1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyIgPjwvZGl2Pgo8L2JvZHk+CjxzY3JpcHQ+ICAgIAogICAgCiAgICAKICAgICAgICB2YXIgYm91bmRzID0gbnVsbDsKICAgIAoKICAgIHZhciBtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMgPSBMLm1hcCgKICAgICAgICAnbWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjJywgewogICAgICAgIGNlbnRlcjogWzI4LjQ5MjUsIDgwLjkwNjVdLAogICAgICAgIHpvb206IDExLAogICAgICAgIG1heEJvdW5kczogYm91bmRzLAogICAgICAgIGxheWVyczogW10sCiAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICB9KTsKCgogICAgCiAgICB2YXIgdGlsZV9sYXllcl8yZTkxNmRkNGJhYTU0NzNhYWVjZTQyMmRmZTFhZTU1ZSA9IEwudGlsZUxheWVyKAogICAgICAgICdodHRwczovL3N0YW1lbi10aWxlcy17c30uYS5zc2wuZmFzdGx5Lm5ldC90ZXJyYWluL3t6fS97eH0ve3l9LmpwZycsCiAgICAgICAgewogICAgICAgICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgICAgICAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICAgICAgICJtYXhOYXRpdmVab29tIjogMTgsCiAgICAgICAgIm1heFpvb20iOiAxOCwKICAgICAgICAibWluWm9vbSI6IDAsCiAgICAgICAgIm5vV3JhcCI6IGZhbHNlLAogICAgICAgICJvcGFjaXR5IjogMSwKICAgICAgICAic3ViZG9tYWlucyI6ICJhYmMiLAogICAgICAgICJ0bXMiOiBmYWxzZQp9KS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgCiAgICAgICAgdmFyIG1hcmtlcl83NjhkMGEzYzcwMjQ0NTczODM5ZDMzZDc0YTE2YjFkNiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguOTgsIDgwLjE5M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ0ZWE3N2MwZmQwMDQwNmI5ZWM1YmNmMzhiOTQ2MjA3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcyMTNlMmQ5NDNlZTRjZjI5Y2NkZWIyZjZiMWJkMDBhID0gJChgPGRpdiBpZD0iaHRtbF83MjEzZTJkOTQzZWU0Y2YyOWNjZGViMmY2YjFiZDAwYSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogQmFuZ2FuZ2EsICAgWWllbGQgNTMuOTI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ0ZWE3N2MwZmQwMDQwNmI5ZWM1YmNmMzhiOTQ2MjA3LnNldENvbnRlbnQoaHRtbF83MjEzZTJkOTQzZWU0Y2YyOWNjZGViMmY2YjFiZDAwYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzc2OGQwYTNjNzAyNDQ1NzM4MzlkMzNkNzRhMTZiMWQ2LmJpbmRQb3B1cChwb3B1cF80NGVhNzdjMGZkMDA0MDZiOWVjNWJjZjM4Yjk0NjIwNykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNzY4ZDBhM2M3MDI0NDU3MzgzOWQzM2Q3NGExNmIxZDYuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOGIwYzJlMWExOTIxNDc5NzlhMDg4ZWViNTAwYWYyNjYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljk4LCA4MC4xOTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wNjc3NGY4MGI3YTc0ZDkzODNiNWIzMjQ4MDllYjU0MCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZjAzMWJhYWM3YWY0M2E3OWU5YTE5Y2JjMTYzNzA1MyA9ICQoYDxkaXYgaWQ9Imh0bWxfM2YwMzFiYWFjN2FmNDNhNzllOWExOWNiYzE2MzcwNTMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFRpbGdhbmdhLCAgIFlpZWxkIDUwLjYyPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wNjc3NGY4MGI3YTc0ZDkzODNiNWIzMjQ4MDllYjU0MC5zZXRDb250ZW50KGh0bWxfM2YwMzFiYWFjN2FmNDNhNzllOWExOWNiYzE2MzcwNTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84YjBjMmUxYTE5MjE0Nzk3OWEwODhlZWI1MDBhZjI2Ni5iaW5kUG9wdXAocG9wdXBfMDY3NzRmODBiN2E3NGQ5MzgzYjViMzI0ODA5ZWI1NDApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzhiMGMyZTFhMTkyMTQ3OTc5YTA4OGVlYjUwMGFmMjY2LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzI1M2Q0MjIyYmEzMDRmZDdhMzM4Yjc3NWYwMzMxOWRkID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC45OCwgODAuMTkzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTI0NjBlNWExMDE3NGRhYjhkZTM4ZjVhY2VlM2RmYjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTY3YTE5ZjY1M2E2NDBlZjkyNGI5MmEyOWRhMmE0NjIgPSAkKGA8ZGl2IGlkPSJodG1sXzE2N2ExOWY2NTNhNjQwZWY5MjRiOTJhMjlkYTJhNDYyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOSFMgMTc1NSwgICBZaWVsZCA0MC40NDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTI0NjBlNWExMDE3NGRhYjhkZTM4ZjVhY2VlM2RmYjUuc2V0Q29udGVudChodG1sXzE2N2ExOWY2NTNhNjQwZWY5MjRiOTJhMjlkYTJhNDYyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMjUzZDQyMjJiYTMwNGZkN2EzMzhiNzc1ZjAzMzE5ZGQuYmluZFBvcHVwKHBvcHVwXzkyNDYwZTVhMTAxNzRkYWI4ZGUzOGY1YWNlZTNkZmI1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8yNTNkNDIyMmJhMzA0ZmQ3YTMzOGI3NzVmMDMzMTlkZC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84MDZhMmVhMmJiNWU0MDY3OTFmMjcwNWRhYzc4Nzc4NyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguOTg2LCA4MC4xODhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yYTIwOGNhMzI4ZWQ0MjNjODBhNTQwNTk3NjE5ZGY5YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82Nzc1MDRlNTI2MDc0MzM4OTU4NmE3MzY0NjQxN2RlNiA9ICQoYDxkaXYgaWQ9Imh0bWxfNjc3NTA0ZTUyNjA3NDMzODk1ODZhNzM2NDY0MTdkZTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0Ni4zMjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmEyMDhjYTMyOGVkNDIzYzgwYTU0MDU5NzYxOWRmOWIuc2V0Q29udGVudChodG1sXzY3NzUwNGU1MjYwNzQzMzg5NTg2YTczNjQ2NDE3ZGU2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODA2YTJlYTJiYjVlNDA2NzkxZjI3MDVkYWM3ODc3ODcuYmluZFBvcHVwKHBvcHVwXzJhMjA4Y2EzMjhlZDQyM2M4MGE1NDA1OTc2MTlkZjliKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84MDZhMmVhMmJiNWU0MDY3OTFmMjcwNWRhYzc4Nzc4Ny5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9lMWFiODVhNTdkZTI0ZDRiYjM0ZmE2OGRjMTYxY2JlMSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguOTg2LCA4MC4xODhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yODg4N2QxYjJmMzU0MmY0YTllNjFjMTEyMDQ0YTg2OSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNTczMjhiMDNjM2M0NWJiYTM4NDYyZjQzMDI4NmM1YyA9ICQoYDxkaXYgaWQ9Imh0bWxfMzU3MzI4YjAzYzNjNDViYmEzODQ2MmY0MzAyODZjNWMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDYyLjU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzI4ODg3ZDFiMmYzNTQyZjRhOWU2MWMxMTIwNDRhODY5LnNldENvbnRlbnQoaHRtbF8zNTczMjhiMDNjM2M0NWJiYTM4NDYyZjQzMDI4NmM1Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2UxYWI4NWE1N2RlMjRkNGJiMzRmYTY4ZGMxNjFjYmUxLmJpbmRQb3B1cChwb3B1cF8yODg4N2QxYjJmMzU0MmY0YTllNjFjMTEyMDQ0YTg2OSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZTFhYjg1YTU3ZGUyNGQ0YmIzNGZhNjhkYzE2MWNiZTEuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOWEzOGI1NDU3YThiNDMxZTkxNGI5ODM4YjQwMzBiMTkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljk4NiwgODAuMTg4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTEyNTE1ZTNjOTM2NGNlNGE4MGU3Mjg5MDQ3Mzg0Y2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWFmNGYyZGZiMmEyNGQ4Y2JhZTBmZWI5ZTRlMTk0YWIgPSAkKGA8ZGl2IGlkPSJodG1sX2FhZjRmMmRmYjJhMjRkOGNiYWUwZmViOWU0ZTE5NGFiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1Ny4zNDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTEyNTE1ZTNjOTM2NGNlNGE4MGU3Mjg5MDQ3Mzg0Y2Quc2V0Q29udGVudChodG1sX2FhZjRmMmRmYjJhMjRkOGNiYWUwZmViOWU0ZTE5NGFiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOWEzOGI1NDU3YThiNDMxZTkxNGI5ODM4YjQwMzBiMTkuYmluZFBvcHVwKHBvcHVwXzUxMjUxNWUzYzkzNjRjZTRhODBlNzI4OTA0NzM4NGNkKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85YTM4YjU0NTdhOGI0MzFlOTE0Yjk4MzhiNDAzMGIxOS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yMzgzN2ExNjUxM2U0MDdmOTA3ZTA0M2ZlYzZmMmRmNCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguOTY4LCA4MC4xNjVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lYWJmZWU3NjQ4YTg0OWQ1ODNhNWU5MWViMTk5OTI4NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xZjkyMzBlNDBiOTU0OGFiOGM1ZjhhYTZlYTdkMmExNiA9ICQoYDxkaXYgaWQ9Imh0bWxfMWY5MjMwZTQwYjk1NDhhYjhjNWY4YWE2ZWE3ZDJhMTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0NS45MTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZWFiZmVlNzY0OGE4NDlkNTgzYTVlOTFlYjE5OTkyODUuc2V0Q29udGVudChodG1sXzFmOTIzMGU0MGI5NTQ4YWI4YzVmOGFhNmVhN2QyYTE2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMjM4MzdhMTY1MTNlNDA3ZjkwN2UwNDNmZWM2ZjJkZjQuYmluZFBvcHVwKHBvcHVwX2VhYmZlZTc2NDhhODQ5ZDU4M2E1ZTkxZWIxOTk5Mjg1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8yMzgzN2ExNjUxM2U0MDdmOTA3ZTA0M2ZlYzZmMmRmNC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mODIyMzI4MDNjZjQ0MWM1OTFmNzFmZGE4ZmMxYTQ1YyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguOTY4LCA4MC4xNjVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yNzVhZDI5NDcwYzY0MjVmYWJjY2Y4YWI3ZDI1M2U4MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zY2E0MDZkZjhmMGM0NWE4OTg4YWIxMjQ3OWUyYjg4OCA9ICQoYDxkaXYgaWQ9Imh0bWxfM2NhNDA2ZGY4ZjBjNDVhODk4OGFiMTI0NzllMmI4ODgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5IUyAxNzU1LCAgIFlpZWxkIDQ5Ljg0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yNzVhZDI5NDcwYzY0MjVmYWJjY2Y4YWI3ZDI1M2U4My5zZXRDb250ZW50KGh0bWxfM2NhNDA2ZGY4ZjBjNDVhODk4OGFiMTI0NzllMmI4ODgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9mODIyMzI4MDNjZjQ0MWM1OTFmNzFmZGE4ZmMxYTQ1Yy5iaW5kUG9wdXAocG9wdXBfMjc1YWQyOTQ3MGM2NDI1ZmFiY2NmOGFiN2QyNTNlODMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2Y4MjIzMjgwM2NmNDQxYzU5MWY3MWZkYThmYzFhNDVjLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2FhN2JkMzA5OGY2NjRjZjFiYWQzYjlmODliNDg2NDhiID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC45NjgsIDgwLjE2NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNmOGRmZDY0YjI5YjQwNmNhZTNhNjY0MDU4MjNmZmQ4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2M2YjliYmI1YzYwMDQ1NGFiN2IwMDA4NDBlNTY5YmJlID0gJChgPGRpdiBpZD0iaHRtbF9jNmI5YmJiNWM2MDA0NTRhYjdiMDAwODQwZTU2OWJiZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkhTIDE3NTUsICAgWWllbGQgNDQuOTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfM2Y4ZGZkNjRiMjliNDA2Y2FlM2E2NjQwNTgyM2ZmZDguc2V0Q29udGVudChodG1sX2M2YjliYmI1YzYwMDQ1NGFiN2IwMDA4NDBlNTY5YmJlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYWE3YmQzMDk4ZjY2NGNmMWJhZDNiOWY4OWI0ODY0OGIuYmluZFBvcHVwKHBvcHVwXzNmOGRmZDY0YjI5YjQwNmNhZTNhNjY0MDU4MjNmZmQ4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9hYTdiZDMwOThmNjY0Y2YxYmFkM2I5Zjg5YjQ4NjQ4Yi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81NDc0OGIzNzlmZjY0ZWQ3OTFjMDUwMzkwMGFiZmYwMSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguODUxLCA4MC41M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU4ZGU0YjAwN2ZkMjRjMjNiOTA0ZGRmYzhlMDA1NjQ5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhlMDNhYjBlNWNlYzQyMmNhNzJiNjQ4OTQ0ZDAxNGYwID0gJChgPGRpdiBpZD0iaHRtbF84ZTAzYWIwZTVjZWM0MjJjYTcyYjY0ODk0NGQwMTRmMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDUzLjA0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81OGRlNGIwMDdmZDI0YzIzYjkwNGRkZmM4ZTAwNTY0OS5zZXRDb250ZW50KGh0bWxfOGUwM2FiMGU1Y2VjNDIyY2E3MmI2NDg5NDRkMDE0ZjApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl81NDc0OGIzNzlmZjY0ZWQ3OTFjMDUwMzkwMGFiZmYwMS5iaW5kUG9wdXAocG9wdXBfNThkZTRiMDA3ZmQyNGMyM2I5MDRkZGZjOGUwMDU2NDkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzU0NzQ4YjM3OWZmNjRlZDc5MWMwNTAzOTAwYWJmZjAxLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2I3ZDUyMzM1NzEwMzQ4ZjY4YTg3MTQ2MjdlNDI3YWJhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC44NTEsIDgwLjUzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTI5ZTYzZjkyMjMxNGIwMmEzMTQwMzkyMzk4YmMyZjYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTQ2NWFkMTE0MzUxNDkxNzg3MzM1NzJlNTc1NWZiYTIgPSAkKGA8ZGl2IGlkPSJodG1sXzU0NjVhZDExNDM1MTQ5MTc4NzMzNTcyZTU3NTVmYmEyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBBZGl0eWEsICAgWWllbGQgNDguMDE8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzEyOWU2M2Y5MjIzMTRiMDJhMzE0MDM5MjM5OGJjMmY2LnNldENvbnRlbnQoaHRtbF81NDY1YWQxMTQzNTE0OTE3ODczMzU3MmU1NzU1ZmJhMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2I3ZDUyMzM1NzEwMzQ4ZjY4YTg3MTQ2MjdlNDI3YWJhLmJpbmRQb3B1cChwb3B1cF8xMjllNjNmOTIyMzE0YjAyYTMxNDAzOTIzOThiYzJmNikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYjdkNTIzMzU3MTAzNDhmNjhhODcxNDYyN2U0MjdhYmEuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYzllMWEzNTIwNWUyNDZhZTlmYjBiODMxZjExOWQ4MTUgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljg1MSwgODAuNTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xZTMxNWI2MWU3NDU0YzA1OTk0NTA1YTc3NWJkMDQ5NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80N2I1ZTFlYjIxMzQ0YTc4YWExMWNkZWNlZmM2YjFmNCA9ICQoYDxkaXYgaWQ9Imh0bWxfNDdiNWUxZWIyMTM0NGE3OGFhMTFjZGVjZWZjNmIxZjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEFkaXR5YSwgICBZaWVsZCA0NS4wNDU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFlMzE1YjYxZTc0NTRjMDU5OTQ1MDVhNzc1YmQwNDk3LnNldENvbnRlbnQoaHRtbF80N2I1ZTFlYjIxMzQ0YTc4YWExMWNkZWNlZmM2YjFmNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2M5ZTFhMzUyMDVlMjQ2YWU5ZmIwYjgzMWYxMTlkODE1LmJpbmRQb3B1cChwb3B1cF8xZTMxNWI2MWU3NDU0YzA1OTk0NTA1YTc3NWJkMDQ5NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYzllMWEzNTIwNWUyNDZhZTlmYjBiODMxZjExOWQ4MTUuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMjhjNDkzOGQxNWRkNGI3MjkyZjFlZjdiNGNmNTM4NTYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjgyLCA4MC41MjNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNDdjOTlmNTE3OTY0MDFlOTg0YWJhMTcxZTRkYzk0NCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNTA3OTlhOTViYTE0ZjVlOGNmNDY4ODc0NjAwNWMwZiA9ICQoYDxkaXYgaWQ9Imh0bWxfMTUwNzk5YTk1YmExNGY1ZThjZjQ2ODg3NDYwMDVjMGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA2My4wMzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzQ3Yzk5ZjUxNzk2NDAxZTk4NGFiYTE3MWU0ZGM5NDQuc2V0Q29udGVudChodG1sXzE1MDc5OWE5NWJhMTRmNWU4Y2Y0Njg4NzQ2MDA1YzBmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMjhjNDkzOGQxNWRkNGI3MjkyZjFlZjdiNGNmNTM4NTYuYmluZFBvcHVwKHBvcHVwX2M0N2M5OWY1MTc5NjQwMWU5ODRhYmExNzFlNGRjOTQ0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8yOGM0OTM4ZDE1ZGQ0YjcyOTJmMWVmN2I0Y2Y1Mzg1Ni5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl82ZDk1MmM5NDZlN2Q0NWYwOGI5ZTkyNWY2ODAxNjkzYyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguODIsIDgwLjUyM10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzgyNmRmMThjMjM1NjQzZDBhOGVkMzQ0ZjBjYjA4ZjM0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzgyOWE4NTQ3M2E3NDQxMTk4NWQxYmI0MzhkZWFiNWQxID0gJChgPGRpdiBpZD0iaHRtbF84MjlhODU0NzNhNzQ0MTE5ODVkMWJiNDM4ZGVhYjVkMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogQWRpdHlhLCAgIFlpZWxkIDUwLjIxPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84MjZkZjE4YzIzNTY0M2QwYThlZDM0NGYwY2IwOGYzNC5zZXRDb250ZW50KGh0bWxfODI5YTg1NDczYTc0NDExOTg1ZDFiYjQzOGRlYWI1ZDEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82ZDk1MmM5NDZlN2Q0NWYwOGI5ZTkyNWY2ODAxNjkzYy5iaW5kUG9wdXAocG9wdXBfODI2ZGYxOGMyMzU2NDNkMGE4ZWQzNDRmMGNiMDhmMzQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzZkOTUyYzk0NmU3ZDQ1ZjA4YjllOTI1ZjY4MDE2OTNjLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzkzNWM2MGM0NTJlNjQxOGM4MDlmODYyODA1Njc1Mzg1ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC44MiwgODAuNTIzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjg4MzAyZDRiNDQ3NDRkZWIwNThkZjA3ZTM0M2IyZTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjVjNDQ1NDBjNDM4NDc0MjkxYjUzMjBhOTU5ZmU0N2YgPSAkKGA8ZGl2IGlkPSJodG1sXzY1YzQ0NTQwYzQzODQ3NDI5MWI1MzIwYTk1OWZlNDdmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBBZGl0eWEsICAgWWllbGQgNDUuNTk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I4ODMwMmQ0YjQ0NzQ0ZGViMDU4ZGYwN2UzNDNiMmU5LnNldENvbnRlbnQoaHRtbF82NWM0NDU0MGM0Mzg0NzQyOTFiNTMyMGE5NTlmZTQ3Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzkzNWM2MGM0NTJlNjQxOGM4MDlmODYyODA1Njc1Mzg1LmJpbmRQb3B1cChwb3B1cF9iODgzMDJkNGI0NDc0NGRlYjA1OGRmMDdlMzQzYjJlOSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTM1YzYwYzQ1MmU2NDE4YzgwOWY4NjI4MDU2NzUzODUuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMmJjNmQzMTA0NGViNDk0Nzk2MDM5MjM0NWE2M2ZiZjEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjgxNCwgODAuNTc0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfN2E1NTUwYjgyNmFhNGFhZjgzMGYxMmMwODliNmYzMjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDZmMDk3ZDU2NTBiNDExMTliYjQzODM4YWFkNjYxYWEgPSAkKGA8ZGl2IGlkPSJodG1sXzQ2ZjA5N2Q1NjUwYjQxMTE5YmI0MzgzOGFhZDY2MWFhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA1NC43PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83YTU1NTBiODI2YWE0YWFmODMwZjEyYzA4OWI2ZjMyNC5zZXRDb250ZW50KGh0bWxfNDZmMDk3ZDU2NTBiNDExMTliYjQzODM4YWFkNjYxYWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8yYmM2ZDMxMDQ0ZWI0OTQ3OTYwMzkyMzQ1YTYzZmJmMS5iaW5kUG9wdXAocG9wdXBfN2E1NTUwYjgyNmFhNGFhZjgzMGYxMmMwODliNmYzMjQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzJiYzZkMzEwNDRlYjQ5NDc5NjAzOTIzNDVhNjNmYmYxLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2I4NTY4NGVjMGFiNzQyMDc5ZjA4MGUyMmNlM2RjOTBiID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC44MTQsIDgwLjU3NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E2NmNlNDNlZTg4NjQ1MDY4YzExYTc4MWVmMjY1Y2Y2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUzMTQ1NTRkZDJlMTQ4OWRiOTU0MzMyMzUxM2NiMThhID0gJChgPGRpdiBpZD0iaHRtbF81MzE0NTU0ZGQyZTE0ODlkYjk1NDMzMjM1MTNjYjE4YSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogQWRpdHlhLCAgIFlpZWxkIDUyLjQ3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNjZjZTQzZWU4ODY0NTA2OGMxMWE3ODFlZjI2NWNmNi5zZXRDb250ZW50KGh0bWxfNTMxNDU1NGRkMmUxNDg5ZGI5NTQzMzIzNTEzY2IxOGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9iODU2ODRlYzBhYjc0MjA3OWYwODBlMjJjZTNkYzkwYi5iaW5kUG9wdXAocG9wdXBfYTY2Y2U0M2VlODg2NDUwNjhjMTFhNzgxZWYyNjVjZjYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2I4NTY4NGVjMGFiNzQyMDc5ZjA4MGUyMmNlM2RjOTBiLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzcwMWMzYThmNTY1YjRlMjM4OWMyMGYxYmUwNjM1MDEwID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC44MTQsIDgwLjU3NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA1YTYwYjZlNmY4YTRjNjE5OTcyZjZjMTAxMzliN2M1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk0ZjQ4NzczYTJkMTQ2N2NiYTEyYzJhOWIyMzViYzI1ID0gJChgPGRpdiBpZD0iaHRtbF85NGY0ODc3M2EyZDE0NjdjYmExMmMyYTliMjM1YmMyNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogQWRpdHlhLCAgIFlpZWxkIDUxLjI3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wNWE2MGI2ZTZmOGE0YzYxOTk3MmY2YzEwMTM5YjdjNS5zZXRDb250ZW50KGh0bWxfOTRmNDg3NzNhMmQxNDY3Y2JhMTJjMmE5YjIzNWJjMjUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83MDFjM2E4ZjU2NWI0ZTIzODljMjBmMWJlMDYzNTAxMC5iaW5kUG9wdXAocG9wdXBfMDVhNjBiNmU2ZjhhNGM2MTk5NzJmNmMxMDEzOWI3YzUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzcwMWMzYThmNTY1YjRlMjM4OWMyMGYxYmUwNjM1MDEwLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2I1NzJlNGJkOGExZTRmM2RiMTljNzNiNzljMWVjZDNjID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4yNjksIDgxLjM3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWFiYTFmNDkzYTQ4NGFkMmE0ZDRlYmQ2Y2YxY2FmMzcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjgwNzE3ZjRiODhjNDhjYWExNDMyM2Y2MjM4ZTNjYjcgPSAkKGA8ZGl2IGlkPSJodG1sXzY4MDcxN2Y0Yjg4YzQ4Y2FhMTQzMjNmNjIzOGUzY2I3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA0OS42OTU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFhYmExZjQ5M2E0ODRhZDJhNGQ0ZWJkNmNmMWNhZjM3LnNldENvbnRlbnQoaHRtbF82ODA3MTdmNGI4OGM0OGNhYTE0MzIzZjYyMzhlM2NiNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2I1NzJlNGJkOGExZTRmM2RiMTljNzNiNzljMWVjZDNjLmJpbmRQb3B1cChwb3B1cF8xYWJhMWY0OTNhNDg0YWQyYTRkNGViZDZjZjFjYWYzNykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYjU3MmU0YmQ4YTFlNGYzZGIxOWM3M2I3OWMxZWNkM2MuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYTZiYWZhNTcxMTU2NDUwOThkM2NhMTQ2MzgzNTNkZjYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjI2OSwgODEuMzddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83NmNiZTBiMjU3MTY0MDIyYWU0OGU1NGVmOGZjMmU1ZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZTI1NTNiMWEyNTM0NTNhOTkyOWU4MGI2Y2YyNTUxMSA9ICQoYDxkaXYgaWQ9Imh0bWxfM2UyNTUzYjFhMjUzNDUzYTk5MjllODBiNmNmMjU1MTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDUxLjA1NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzZjYmUwYjI1NzE2NDAyMmFlNDhlNTRlZjhmYzJlNWUuc2V0Q29udGVudChodG1sXzNlMjU1M2IxYTI1MzQ1M2E5OTI5ZTgwYjZjZjI1NTExKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYTZiYWZhNTcxMTU2NDUwOThkM2NhMTQ2MzgzNTNkZjYuYmluZFBvcHVwKHBvcHVwXzc2Y2JlMGIyNTcxNjQwMjJhZTQ4ZTU0ZWY4ZmMyZTVlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9hNmJhZmE1NzExNTY0NTA5OGQzY2ExNDYzODM1M2RmNi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jOGVhMDE4YmVhMTU0NDliYjg4YzRkODI5YmEyMDQ3YSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMjY5LCA4MS4zN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2EzZDU1M2FjMGZiZDQzMGFiMDEzNGI1NTMxNmY0M2E0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ5OTRmZWUwMzRiODQyODhhZDc0NDA5MjMzMmYzNjkzID0gJChgPGRpdiBpZD0iaHRtbF80OTk0ZmVlMDM0Yjg0Mjg4YWQ3NDQwOTIzMzJmMzY5MyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNTMuMTI4PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hM2Q1NTNhYzBmYmQ0MzBhYjAxMzRiNTUzMTZmNDNhNC5zZXRDb250ZW50KGh0bWxfNDk5NGZlZTAzNGI4NDI4OGFkNzQ0MDkyMzMyZjM2OTMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9jOGVhMDE4YmVhMTU0NDliYjg4YzRkODI5YmEyMDQ3YS5iaW5kUG9wdXAocG9wdXBfYTNkNTUzYWMwZmJkNDMwYWIwMTM0YjU1MzE2ZjQzYTQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2M4ZWEwMThiZWExNTQ0OWJiODhjNGQ4MjliYTIwNDdhLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzdjODgxNWViZDhjMzRjYWE4NGU5ZGQyZGJkOTFiYzY0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4yNzcsIDgxLjM2Nl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJkNjZmNzM2MmExNTQzOGViZjY1N2VjYTdhZWU0NGU1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E3NDk0Zjk0OTAwOTQ4ODQ4YzNkZTY4MTZhZWU2NzY5ID0gJChgPGRpdiBpZD0iaHRtbF9hNzQ5NGY5NDkwMDk0ODg0OGMzZGU2ODE2YWVlNjc2OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQ2Ljk1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yZDY2ZjczNjJhMTU0MzhlYmY2NTdlY2E3YWVlNDRlNS5zZXRDb250ZW50KGh0bWxfYTc0OTRmOTQ5MDA5NDg4NDhjM2RlNjgxNmFlZTY3NjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83Yzg4MTVlYmQ4YzM0Y2FhODRlOWRkMmRiZDkxYmM2NC5iaW5kUG9wdXAocG9wdXBfMmQ2NmY3MzYyYTE1NDM4ZWJmNjU3ZWNhN2FlZTQ0ZTUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzdjODgxNWViZDhjMzRjYWE4NGU5ZGQyZGJkOTFiYzY0LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzFmNmZiNDc1ZDIyNDQyMWNiNWVlMTdiYjA5YWIyMDk2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4yNzcsIDgxLjM2NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I4ZTA1NThmZWExNTRkN2I4NzZiZTBmZmM4ZWRhZWU0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI1Y2EzM2RlY2M4ZDRkMmViYmNmZjgwN2I4MmQxOWEyID0gJChgPGRpdiBpZD0iaHRtbF8yNWNhMzNkZWNjOGQ0ZDJlYmJjZmY4MDdiODJkMTlhMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVGlsb3R0YW1hLCAgIFlpZWxkIDQyLjM2MTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjhlMDU1OGZlYTE1NGQ3Yjg3NmJlMGZmYzhlZGFlZTQuc2V0Q29udGVudChodG1sXzI1Y2EzM2RlY2M4ZDRkMmViYmNmZjgwN2I4MmQxOWEyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMWY2ZmI0NzVkMjI0NDIxY2I1ZWUxN2JiMDlhYjIwOTYuYmluZFBvcHVwKHBvcHVwX2I4ZTA1NThmZWExNTRkN2I4NzZiZTBmZmM4ZWRhZWU0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8xZjZmYjQ3NWQyMjQ0MjFjYjVlZTE3YmIwOWFiMjA5Ni5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iNDhhMjFkY2NiNmM0MjAyOTcxYWNkZGYzMmVmZTExNCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMjc3LCA4MS4zNjVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83Yzk0YWI2MTc5YzU0OWNkOTY2ZWViNjFmMzNjOGMyYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNTQ5OWJlN2JjY2Y0OTBlYjYzZTY5ZWI2ODNmNGFiMyA9ICQoYDxkaXYgaWQ9Imh0bWxfYzU0OTliZTdiY2NmNDkwZWI2M2U2OWViNjgzZjRhYjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFRpbG90dGFtYSwgICBZaWVsZCA0My40NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2M5NGFiNjE3OWM1NDljZDk2NmVlYjYxZjMzYzhjMmIuc2V0Q29udGVudChodG1sX2M1NDk5YmU3YmNjZjQ5MGViNjNlNjllYjY4M2Y0YWIzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYjQ4YTIxZGNjYjZjNDIwMjk3MWFjZGRmMzJlZmUxMTQuYmluZFBvcHVwKHBvcHVwXzdjOTRhYjYxNzljNTQ5Y2Q5NjZlZWI2MWYzM2M4YzJiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9iNDhhMjFkY2NiNmM0MjAyOTcxYWNkZGYzMmVmZTExNC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mNGJlZTZmOWI1NWY0YWI3OGYxYjM3MjIwZWMwMGY1ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMjgxLCA4MS4zODVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yOWM2NjMxMGMzYWQ0ZWQwYmU3YzcyNGVlM2YzOTUyZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83YmEzZGJiNGNmMmI0MmJmOTU1ZjgwODI4NTkyOGNmMCA9ICQoYDxkaXYgaWQ9Imh0bWxfN2JhM2RiYjRjZjJiNDJiZjk1NWY4MDgyODU5MjhjZjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDQ5LjU0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yOWM2NjMxMGMzYWQ0ZWQwYmU3YzcyNGVlM2YzOTUyZC5zZXRDb250ZW50KGh0bWxfN2JhM2RiYjRjZjJiNDJiZjk1NWY4MDgyODU5MjhjZjApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9mNGJlZTZmOWI1NWY0YWI3OGYxYjM3MjIwZWMwMGY1ZS5iaW5kUG9wdXAocG9wdXBfMjljNjYzMTBjM2FkNGVkMGJlN2M3MjRlZTNmMzk1MmQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2Y0YmVlNmY5YjU1ZjRhYjc4ZjFiMzcyMjBlYzAwZjVlLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzVkZTk4ZTk0YjVmNzRmMjA5MDAyYzUxYTQ0ZmU3YzdkID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4yODEsIDgxLjM4NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E1YTk0MTVjOTc3NDQ1ZDJiMDk5ZmMxNTNmNTBjNjJjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUwN2E4MjgyNjhkZTRiNTRhZDhiYTE4MzNkZTM5Mzk5ID0gJChgPGRpdiBpZD0iaHRtbF81MDdhODI4MjY4ZGU0YjU0YWQ4YmExODMzZGUzOTM5OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDguODk1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNWE5NDE1Yzk3NzQ0NWQyYjA5OWZjMTUzZjUwYzYyYy5zZXRDb250ZW50KGh0bWxfNTA3YTgyODI2OGRlNGI1NGFkOGJhMTgzM2RlMzkzOTkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl81ZGU5OGU5NGI1Zjc0ZjIwOTAwMmM1MWE0NGZlN2M3ZC5iaW5kUG9wdXAocG9wdXBfYTVhOTQxNWM5Nzc0NDVkMmIwOTlmYzE1M2Y1MGM2MmMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzVkZTk4ZTk0YjVmNzRmMjA5MDAyYzUxYTQ0ZmU3YzdkLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2U3YmVmMWVmNzA4YzRiZGI4MmJhMzNjM2Y5ODE3ZmI3ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4yODIsIDgxLjM4NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzE2OTM2M2E3YWYzNDQ4NmJiMjc0MGVmNTUxMTk2Mjk2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBlNzU1NTVlY2E0YTQ1NjJhZDBmNDM2OTFlZTliNjU2ID0gJChgPGRpdiBpZD0iaHRtbF8wZTc1NTU1ZWNhNGE0NTYyYWQwZjQzNjkxZWU5YjY1NiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDQuNjUxPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xNjkzNjNhN2FmMzQ0ODZiYjI3NDBlZjU1MTE5NjI5Ni5zZXRDb250ZW50KGh0bWxfMGU3NTU1NWVjYTRhNDU2MmFkMGY0MzY5MWVlOWI2NTYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9lN2JlZjFlZjcwOGM0YmRiODJiYTMzYzNmOTgxN2ZiNy5iaW5kUG9wdXAocG9wdXBfMTY5MzYzYTdhZjM0NDg2YmIyNzQwZWY1NTExOTYyOTYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2U3YmVmMWVmNzA4YzRiZGI4MmJhMzNjM2Y5ODE3ZmI3LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzY5YjczMTE1MzMxNjQwOTZhY2JlYWYzMmRmNWM5NGRmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC40NjIsIDgxLjMxNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzUzNGIzMzZmZjNjNzRiNjY5YzEwNzk5ZGI0YjFhZTlmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNkMTNlY2VkZjVlODQ1ZTVhMWM5N2Y2YzhjMGIxZDQ5ID0gJChgPGRpdiBpZD0iaHRtbF8zZDEzZWNlZGY1ZTg0NWU1YTFjOTdmNmM4YzBiMWQ0OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQ5LjE1OTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTM0YjMzNmZmM2M3NGI2NjljMTA3OTlkYjRiMWFlOWYuc2V0Q29udGVudChodG1sXzNkMTNlY2VkZjVlODQ1ZTVhMWM5N2Y2YzhjMGIxZDQ5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNjliNzMxMTUzMzE2NDA5NmFjYmVhZjMyZGY1Yzk0ZGYuYmluZFBvcHVwKHBvcHVwXzUzNGIzMzZmZjNjNzRiNjY5YzEwNzk5ZGI0YjFhZTlmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl82OWI3MzExNTMzMTY0MDk2YWNiZWFmMzJkZjVjOTRkZi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84MjNmZjdmYTRlOTk0MThmYWVhYjA1Yjc3M2RhNTlmNiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDYxLCA4MS4zMTVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81NmUwZTVmNWVhOTQ0ZGIzYjFkN2VlOTFlMDUyMWQ3OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mZTdlNmMyMDQ5NDc0OGU0YmI3NWM0MDU4MWU3MmVlOSA9ICQoYDxkaXYgaWQ9Imh0bWxfZmU3ZTZjMjA0OTQ3NDhlNGJiNzVjNDA1ODFlNzJlZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDU2LjE4MTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTZlMGU1ZjVlYTk0NGRiM2IxZDdlZTkxZTA1MjFkNzguc2V0Q29udGVudChodG1sX2ZlN2U2YzIwNDk0NzQ4ZTRiYjc1YzQwNTgxZTcyZWU5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODIzZmY3ZmE0ZTk5NDE4ZmFlYWIwNWI3NzNkYTU5ZjYuYmluZFBvcHVwKHBvcHVwXzU2ZTBlNWY1ZWE5NDRkYjNiMWQ3ZWU5MWUwNTIxZDc4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84MjNmZjdmYTRlOTk0MThmYWVhYjA1Yjc3M2RhNTlmNi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9hNWQ5NWIzODQxZDk0YmVkOGE1YjZmZjgwYzlkMDFiNSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDYxLCA4MS4zMTRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85NjcwNThiY2RmOWQ0YjdhODZmYTliMWJmMGI0ZGZmNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wY2ZjNzE1YTk5MjQ0YmZlOTliMjgxNzkwZTUwMjkxZiA9ICQoYDxkaXYgaWQ9Imh0bWxfMGNmYzcxNWE5OTI0NGJmZTk5YjI4MTc5MGU1MDI5MWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDU2LjA5ODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTY3MDU4YmNkZjlkNGI3YTg2ZmE5YjFiZjBiNGRmZjUuc2V0Q29udGVudChodG1sXzBjZmM3MTVhOTkyNDRiZmU5OWIyODE3OTBlNTAyOTFmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYTVkOTViMzg0MWQ5NGJlZDhhNWI2ZmY4MGM5ZDAxYjUuYmluZFBvcHVwKHBvcHVwXzk2NzA1OGJjZGY5ZDRiN2E4NmZhOWIxYmYwYjRkZmY1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9hNWQ5NWIzODQxZDk0YmVkOGE1YjZmZjgwYzlkMDFiNS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85NzczNzk3NjY3Mzc0ZTVhYmQ0NTg0ODNlYjc3OWUyYyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDQ4LCA4MS4zMTZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jMTM3MjY3OTkyZjQ0NDhmOWZjNzA0MmQyZTdhOWFkMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kMDJmMTMwMTA2NzY0MjIzODhlODA0Nzc2MGYzY2RkOCA9ICQoYDxkaXYgaWQ9Imh0bWxfZDAyZjEzMDEwNjc2NDIyMzg4ZTgwNDc3NjBmM2NkZDgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDUzLjExNDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzEzNzI2Nzk5MmY0NDQ4ZjlmYzcwNDJkMmU3YTlhZDAuc2V0Q29udGVudChodG1sX2QwMmYxMzAxMDY3NjQyMjM4OGU4MDQ3NzYwZjNjZGQ4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOTc3Mzc5NzY2NzM3NGU1YWJkNDU4NDgzZWI3NzllMmMuYmluZFBvcHVwKHBvcHVwX2MxMzcyNjc5OTJmNDQ0OGY5ZmM3MDQyZDJlN2E5YWQwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85NzczNzk3NjY3Mzc0ZTVhYmQ0NTg0ODNlYjc3OWUyYy5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zYTlmZjhmNzQ4ZmY0ODJhYTBkZGRkNmE5ZTczY2Q2MyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDQ4LCA4MS4zMTZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lMzNmZGFiODBhNjI0YTdkYjk5Y2YyODZhYTFlZmE1OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xNGMzNTY0MzY3M2U0NjQxYTFjMWNkNGI5ZDU3MjZmMiA9ICQoYDxkaXYgaWQ9Imh0bWxfMTRjMzU2NDM2NzNlNDY0MWExYzFjZDRiOWQ1NzI2ZjIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ1LjcwOTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTMzZmRhYjgwYTYyNGE3ZGI5OWNmMjg2YWExZWZhNTguc2V0Q29udGVudChodG1sXzE0YzM1NjQzNjczZTQ2NDFhMWMxY2Q0YjlkNTcyNmYyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfM2E5ZmY4Zjc0OGZmNDgyYWEwZGRkZDZhOWU3M2NkNjMuYmluZFBvcHVwKHBvcHVwX2UzM2ZkYWI4MGE2MjRhN2RiOTljZjI4NmFhMWVmYTU4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8zYTlmZjhmNzQ4ZmY0ODJhYTBkZGRkNmE5ZTczY2Q2My5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yMGQyYWU3NjE5ODI0NzAyODEzZTEzMjg2OTNlNmUwNyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDQ4LCA4MS4zMTddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMmJkMDEzZTgyMzI0OWNlODY0NTQyNmVhZjU5MTUyNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85YTA5NzRiYjIwN2M0MDExOWVjMmUzOWJhMGFhZWMwMyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWEwOTc0YmIyMDdjNDAxMTllYzJlMzliYTBhYWVjMDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ0LjA8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2EyYmQwMTNlODIzMjQ5Y2U4NjQ1NDI2ZWFmNTkxNTI3LnNldENvbnRlbnQoaHRtbF85YTA5NzRiYjIwN2M0MDExOWVjMmUzOWJhMGFhZWMwMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzIwZDJhZTc2MTk4MjQ3MDI4MTNlMTMyODY5M2U2ZTA3LmJpbmRQb3B1cChwb3B1cF9hMmJkMDEzZTgyMzI0OWNlODY0NTQyNmVhZjU5MTUyNykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMjBkMmFlNzYxOTgyNDcwMjgxM2UxMzI4NjkzZTZlMDcuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZDNhYzA4MGJmOWUxNDBiZDk4ODQxOTAzYTQzZWZmYzIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQ3LCA4MS4zMjFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lN2RjNDcwZDlkYjE0YjA4YTI0YTI4M2RiMTI0YjhjOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82YzVjNWI2YzFjODM0ZTk2ODYxNWFlZTlhYTUxZTYzYyA9ICQoYDxkaXYgaWQ9Imh0bWxfNmM1YzViNmMxYzgzNGU5Njg2MTVhZWU5YWE1MWU2M2MiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ0LjI4MjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTdkYzQ3MGQ5ZGIxNGIwOGEyNGEyODNkYjEyNGI4Yzkuc2V0Q29udGVudChodG1sXzZjNWM1YjZjMWM4MzRlOTY4NjE1YWVlOWFhNTFlNjNjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZDNhYzA4MGJmOWUxNDBiZDk4ODQxOTAzYTQzZWZmYzIuYmluZFBvcHVwKHBvcHVwX2U3ZGM0NzBkOWRiMTRiMDhhMjRhMjgzZGIxMjRiOGM5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9kM2FjMDgwYmY5ZTE0MGJkOTg4NDE5MDNhNDNlZmZjMi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8wNmQ1MDRhNzMwOGE0ZjdlYjlhYmM2MjkwODg0Mjg0YyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDcsIDgxLjMyMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA4YmE1OWZjYzUwMzRkYjQ5NGYwMmE5YjUwZTE5ZjU1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUxZDVjNjk1YTM5ODQ1MjI5MmMzZDgyNTI0NGViMTFlID0gJChgPGRpdiBpZD0iaHRtbF81MWQ1YzY5NWEzOTg0NTIyOTJjM2Q4MjUyNDRlYjExZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogQmFuZ2FuZ2EsICAgWWllbGQgNTIuMDU0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wOGJhNTlmY2M1MDM0ZGI0OTRmMDJhOWI1MGUxOWY1NS5zZXRDb250ZW50KGh0bWxfNTFkNWM2OTVhMzk4NDUyMjkyYzNkODI1MjQ0ZWIxMWUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8wNmQ1MDRhNzMwOGE0ZjdlYjlhYmM2MjkwODg0Mjg0Yy5iaW5kUG9wdXAocG9wdXBfMDhiYTU5ZmNjNTAzNGRiNDk0ZjAyYTliNTBlMTlmNTUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzA2ZDUwNGE3MzA4YTRmN2ViOWFiYzYyOTA4ODQyODRjLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2QzNzgzM2RmZmNhZDQ2NjA5Y2MzZTk4ODIzNDc0NzE5ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC40NywgODEuMzJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82MGQ5ZTVhYmZkYjg0YjQ2OWIxNGMxODRhZmVhNWUxNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zZjc2NzA2MmQyOWI0YWFmYmRkNzA3YTNkODRkNTVjZCA9ICQoYDxkaXYgaWQ9Imh0bWxfM2Y3NjcwNjJkMjliNGFhZmJkZDcwN2EzZDg0ZDU1Y2QiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDM5Ljc2ODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjBkOWU1YWJmZGI4NGI0NjliMTRjMTg0YWZlYTVlMTQuc2V0Q29udGVudChodG1sXzNmNzY3MDYyZDI5YjRhYWZiZGQ3MDdhM2Q4NGQ1NWNkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZDM3ODMzZGZmY2FkNDY2MDljYzNlOTg4MjM0NzQ3MTkuYmluZFBvcHVwKHBvcHVwXzYwZDllNWFiZmRiODRiNDY5YjE0YzE4NGFmZWE1ZTE0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9kMzc4MzNkZmZjYWQ0NjYwOWNjM2U5ODgyMzQ3NDcxOS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85MmJiYjY4ZTY0YTc0YTI4OGQ0NDUxOTEzOTE1MmM1MSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDE5LCA4MS4xODZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85MTUwMTEzMmNhY2M0Y2E0OTYzMTkxZmU2NzNkODRlMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hYmFhMTFiZjJhNGQ0ZjlhYTc1ODljYWQyMTZlOTE3ZSA9ICQoYDxkaXYgaWQ9Imh0bWxfYWJhYTExYmYyYTRkNGY5YWE3NTg5Y2FkMjE2ZTkxN2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDUxLjAwODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTE1MDExMzJjYWNjNGNhNDk2MzE5MWZlNjczZDg0ZTAuc2V0Q29udGVudChodG1sX2FiYWExMWJmMmE0ZDRmOWFhNzU4OWNhZDIxNmU5MTdlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOTJiYmI2OGU2NGE3NGEyODhkNDQ1MTkxMzkxNTJjNTEuYmluZFBvcHVwKHBvcHVwXzkxNTAxMTMyY2FjYzRjYTQ5NjMxOTFmZTY3M2Q4NGUwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85MmJiYjY4ZTY0YTc0YTI4OGQ0NDUxOTEzOTE1MmM1MS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8xMWM4OGVmZjBkMjk0MDdkYTEwOWJmN2YxNjZiOTU4YSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDE5LCA4MS4xODZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MWIzMDUxYWU1YmI0MDM3ODY5NDRlY2FkNDk0ZDIwZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lODBhZWVkNmUxYTM0OWM3OTRlZDMzMDdkZjQwMWUxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfZTgwYWVlZDZlMWEzNDljNzk0ZWQzMzA3ZGY0MDFlMTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgNTEuODM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzUxYjMwNTFhZTViYjQwMzc4Njk0NGVjYWQ0OTRkMjBmLnNldENvbnRlbnQoaHRtbF9lODBhZWVkNmUxYTM0OWM3OTRlZDMzMDdkZjQwMWUxOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzExYzg4ZWZmMGQyOTQwN2RhMTA5YmY3ZjE2NmI5NThhLmJpbmRQb3B1cChwb3B1cF81MWIzMDUxYWU1YmI0MDM3ODY5NDRlY2FkNDk0ZDIwZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMTFjODhlZmYwZDI5NDA3ZGExMDliZjdmMTY2Yjk1OGEuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfY2UzN2YyODJjNDFkNDdkMmI4NThlZjQ1N2NhNzg4OTAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQxOSwgODEuMTg2XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjMwNjc5ZjY5N2MwNGE0MGFmYTNmMzU3ODcyZjNjMmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZGVjODYzZjQwYzI2NDg5MTk1ZmI5OWU4NjkwZmU5MDkgPSAkKGA8ZGl2IGlkPSJodG1sX2RlYzg2M2Y0MGMyNjQ4OTE5NWZiOTllODY5MGZlOTA5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDUzLjYwMzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjMwNjc5ZjY5N2MwNGE0MGFmYTNmMzU3ODcyZjNjMmMuc2V0Q29udGVudChodG1sX2RlYzg2M2Y0MGMyNjQ4OTE5NWZiOTllODY5MGZlOTA5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfY2UzN2YyODJjNDFkNDdkMmI4NThlZjQ1N2NhNzg4OTAuYmluZFBvcHVwKHBvcHVwX2IzMDY3OWY2OTdjMDRhNDBhZmEzZjM1Nzg3MmYzYzJjKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9jZTM3ZjI4MmM0MWQ0N2QyYjg1OGVmNDU3Y2E3ODg5MC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8xNmIxNzZkNTQ5YTA0OTg4YWNiOTllY2ViMTRiZjhkYyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDUyLCA4MS4xOTZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85YjdjYTQ4ZTkxYzQ0NmFlYWI2YzdkNTZmODQyNzYyZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNDc0MDU2YmNlYTU0MTZlOWQ5N2EzNTQzODAyZWIxMiA9ICQoYDxkaXYgaWQ9Imh0bWxfMzQ3NDA1NmJjZWE1NDE2ZTlkOTdhMzU0MzgwMmViMTIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0Ni44ODk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzliN2NhNDhlOTFjNDQ2YWVhYjZjN2Q1NmY4NDI3NjJkLnNldENvbnRlbnQoaHRtbF8zNDc0MDU2YmNlYTU0MTZlOWQ5N2EzNTQzODAyZWIxMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzE2YjE3NmQ1NDlhMDQ5ODhhY2I5OWVjZWIxNGJmOGRjLmJpbmRQb3B1cChwb3B1cF85YjdjYTQ4ZTkxYzQ0NmFlYWI2YzdkNTZmODQyNzYyZCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMTZiMTc2ZDU0OWEwNDk4OGFjYjk5ZWNlYjE0YmY4ZGMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNGEyY2QyYTFkZDk2NGJjODk5MTc2ODYzYmQwZTUwNGIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQ1MiwgODEuMTk2XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmJiMjFkOGVhZDZlNGVkMTgzMDRiMWZkZGMxNjUyOTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzQ1ZTAyNjMzNDk0NGFhNWI2YzJiOTc4NjJjZDRjOTYgPSAkKGA8ZGl2IGlkPSJodG1sXzc0NWUwMjYzMzQ5NDRhYTViNmMyYjk3ODYyY2Q0Yzk2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA0Ny4yODI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzJiYjIxZDhlYWQ2ZTRlZDE4MzA0YjFmZGRjMTY1MjkxLnNldENvbnRlbnQoaHRtbF83NDVlMDI2MzM0OTQ0YWE1YjZjMmI5Nzg2MmNkNGM5Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzRhMmNkMmExZGQ5NjRiYzg5OTE3Njg2M2JkMGU1MDRiLmJpbmRQb3B1cChwb3B1cF8yYmIyMWQ4ZWFkNmU0ZWQxODMwNGIxZmRkYzE2NTI5MSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNGEyY2QyYTFkZDk2NGJjODk5MTc2ODYzYmQwZTUwNGIuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOWM5ZTM0NWJjN2U5NGNhMTlhMDczYjNjZWJkZDcxYjQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQ1MSwgODEuMTk1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmY5MTBiNTUwYTBhNDc4YWEyOTRlYjY2MjU2NmY2ZTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2Y5ODhkZGQyYTI4NGY2Nzk5YzUzMzRhYjExODFhZDggPSAkKGA8ZGl2IGlkPSJodG1sXzNmOTg4ZGRkMmEyODRmNjc5OWM1MzM0YWIxMTgxYWQ4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA0Ni42MTc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JmOTEwYjU1MGEwYTQ3OGFhMjk0ZWI2NjI1NjZmNmU5LnNldENvbnRlbnQoaHRtbF8zZjk4OGRkZDJhMjg0ZjY3OTljNTMzNGFiMTE4MWFkOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzljOWUzNDViYzdlOTRjYTE5YTA3M2IzY2ViZGQ3MWI0LmJpbmRQb3B1cChwb3B1cF9iZjkxMGI1NTBhMGE0NzhhYTI5NGViNjYyNTY2ZjZlOSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOWM5ZTM0NWJjN2U5NGNhMTlhMDczYjNjZWJkZDcxYjQuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZTI3Yzg1YTRjMzg0NDUzYmI4MTBkYTE1NjE1NGI5ODIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQyOSwgODEuMTgxXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTcwZWYxYTg5NzZjNGMzMjhkMzU4NjM5ZjdhMWJhMmQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTkyNjI5YzMwYjYzNDg0Njg4ODYyZjM4NmJmOTY3MjQgPSAkKGA8ZGl2IGlkPSJodG1sX2U5MjYyOWMzMGI2MzQ4NDY4ODg2MmYzODZiZjk2NzI0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDYuMTg0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lNzBlZjFhODk3NmM0YzMyOGQzNTg2MzlmN2ExYmEyZC5zZXRDb250ZW50KGh0bWxfZTkyNjI5YzMwYjYzNDg0Njg4ODYyZjM4NmJmOTY3MjQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9lMjdjODVhNGMzODQ0NTNiYjgxMGRhMTU2MTU0Yjk4Mi5iaW5kUG9wdXAocG9wdXBfZTcwZWYxYTg5NzZjNGMzMjhkMzU4NjM5ZjdhMWJhMmQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2UyN2M4NWE0YzM4NDQ1M2JiODEwZGExNTYxNTRiOTgyLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzk5YzMzYTg5NDViOTRlZDdhNmJjOTJmM2ZkNWQyZGE2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC40MjksIDgxLjE4MV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2M4NzQyY2U3ZmY0ZDRkZjE4ZDQ4MTJhZmE0MDE1ZDE5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzA0MzI5ODliOWZmMDQ0MDI5NDQ2MDgyOWE5OWEyZTgyID0gJChgPGRpdiBpZD0iaHRtbF8wNDMyOTg5YjlmZjA0NDAyOTQ0NjA4MjlhOTlhMmU4MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVW5rbm93biwgICBZaWVsZCA0NS4yNjI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M4NzQyY2U3ZmY0ZDRkZjE4ZDQ4MTJhZmE0MDE1ZDE5LnNldENvbnRlbnQoaHRtbF8wNDMyOTg5YjlmZjA0NDAyOTQ0NjA4MjlhOTlhMmU4Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzk5YzMzYTg5NDViOTRlZDdhNmJjOTJmM2ZkNWQyZGE2LmJpbmRQb3B1cChwb3B1cF9jODc0MmNlN2ZmNGQ0ZGYxOGQ0ODEyYWZhNDAxNWQxOSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTljMzNhODk0NWI5NGVkN2E2YmM5MmYzZmQ1ZDJkYTYuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZmYwNDg2NDEwNmY3NDMzMzk4YzEzMjhlZDQ1OTJmNjggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQyOSwgODEuMTgxXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTNiZDZkZjM0OWIwNDBkM2IyZWY2ZjU0ZTU5N2Q1NzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmFjYjc2NmQ5ZWE3NDU5NTgyZDkyM2Y5YTM1ZmMyZjkgPSAkKGA8ZGl2IGlkPSJodG1sXzJhY2I3NjZkOWVhNzQ1OTU4MmQ5MjNmOWEzNWZjMmY5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQ1LjQwNDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTNiZDZkZjM0OWIwNDBkM2IyZWY2ZjU0ZTU5N2Q1NzIuc2V0Q29udGVudChodG1sXzJhY2I3NjZkOWVhNzQ1OTU4MmQ5MjNmOWEzNWZjMmY5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZmYwNDg2NDEwNmY3NDMzMzk4YzEzMjhlZDQ1OTJmNjguYmluZFBvcHVwKHBvcHVwX2UzYmQ2ZGYzNDliMDQwZDNiMmVmNmY1NGU1OTdkNTcyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9mZjA0ODY0MTA2Zjc0MzMzOThjMTMyOGVkNDU5MmY2OC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iOTMwMTk2Njg5ODk0NTljYmZhNzljZmI3OGVjYmE0MCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNDE0LCA4MS4xNDNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hYmM5ZTVmMDUxZWU0NjlhOTBmODIyNzk2ZmZiNTgyMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82MjJhNmVhNzA4YTI0MjhkOGZjN2QzMGM1YmM4ZmMwZiA9ICQoYDxkaXYgaWQ9Imh0bWxfNjIyYTZlYTcwOGEyNDI4ZDhmYzdkMzBjNWJjOGZjMGYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0OS4wMDM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FiYzllNWYwNTFlZTQ2OWE5MGY4MjI3OTZmZmI1ODIzLnNldENvbnRlbnQoaHRtbF82MjJhNmVhNzA4YTI0MjhkOGZjN2QzMGM1YmM4ZmMwZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2I5MzAxOTY2ODk4OTQ1OWNiZmE3OWNmYjc4ZWNiYTQwLmJpbmRQb3B1cChwb3B1cF9hYmM5ZTVmMDUxZWU0NjlhOTBmODIyNzk2ZmZiNTgyMykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYjkzMDE5NjY4OTg5NDU5Y2JmYTc5Y2ZiNzhlY2JhNDAuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmEyMWU0YmZmMmZhNGQ4ZDgzNGZhYzI3ZGJjZTYwNmQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQxNCwgODEuMTQzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmM5OTFiZWNiZTM1NDlhNGE2MGQzNWU1YzQwYTA5NzUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGExNDUzNmRiMTg3NGFlYWExYmZiMGM2YmQ5ZDk2ZTcgPSAkKGA8ZGl2IGlkPSJodG1sXzRhMTQ1MzZkYjE4NzRhZWFhMWJmYjBjNmJkOWQ5NmU3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1My42MTc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JjOTkxYmVjYmUzNTQ5YTRhNjBkMzVlNWM0MGEwOTc1LnNldENvbnRlbnQoaHRtbF80YTE0NTM2ZGIxODc0YWVhYTFiZmIwYzZiZDlkOTZlNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzZhMjFlNGJmZjJmYTRkOGQ4MzRmYWMyN2RiY2U2MDZkLmJpbmRQb3B1cChwb3B1cF9iYzk5MWJlY2JlMzU0OWE0YTYwZDM1ZTVjNDBhMDk3NSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNmEyMWU0YmZmMmZhNGQ4ZDgzNGZhYzI3ZGJjZTYwNmQuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZDEwYTkyMGQ0YWIzNGRkNmE0MmI4MmUxMjI2YmE0ZDEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQxNCwgODEuMTQzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzdhMDU0NjZkZjIxNDk5OGI1NGQ3YjcwOGJlMmE3YTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmZlMDU5NzA2YzQ3NDA0N2ExOWFhNmMwZGUxZTljNTEgPSAkKGA8ZGl2IGlkPSJodG1sX2ZmZTA1OTcwNmM0NzQwNDdhMTlhYTZjMGRlMWU5YzUxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1Ni40ODg8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2M3YTA1NDY2ZGYyMTQ5OThiNTRkN2I3MDhiZTJhN2E0LnNldENvbnRlbnQoaHRtbF9mZmUwNTk3MDZjNDc0MDQ3YTE5YWE2YzBkZTFlOWM1MSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2QxMGE5MjBkNGFiMzRkZDZhNDJiODJlMTIyNmJhNGQxLmJpbmRQb3B1cChwb3B1cF9jN2EwNTQ2NmRmMjE0OTk4YjU0ZDdiNzA4YmUyYTdhNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZDEwYTkyMGQ0YWIzNGRkNmE0MmI4MmUxMjI2YmE0ZDEuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYWM0M2RhMTZhYzIzNGMyZTgzNmEzODhmMTdkZGMzZGYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQwMywgODEuMTU3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTc1M2YzNDgwYjRjNDhhY2IyZWRlNTEwZDI5NDZmZDcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzM4OTNkY2EzOGY5NGQyNTg1NGJhM2IxMWYzMzhmMGEgPSAkKGA8ZGl2IGlkPSJodG1sXzczODkzZGNhMzhmOTRkMjU4NTRiYTNiMTFmMzM4ZjBhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA0MC41MjU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzE3NTNmMzQ4MGI0YzQ4YWNiMmVkZTUxMGQyOTQ2ZmQ3LnNldENvbnRlbnQoaHRtbF83Mzg5M2RjYTM4Zjk0ZDI1ODU0YmEzYjExZjMzOGYwYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2FjNDNkYTE2YWMyMzRjMmU4MzZhMzg4ZjE3ZGRjM2RmLmJpbmRQb3B1cChwb3B1cF8xNzUzZjM0ODBiNGM0OGFjYjJlZGU1MTBkMjk0NmZkNykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYWM0M2RhMTZhYzIzNGMyZTgzNmEzODhmMTdkZGMzZGYuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTkwMGM3YzE1NTY1NGRjZmI1NmI3MjYzN2QxMGY2NDkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQwMywgODEuMTU3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWNlMTYwYmY2ODViNDM4ZTk3M2NmZmY4ODcxY2M0NjUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzYxYTZmZmI5ZDMzNDU5MTgxNWMxMmQ1YmU0N2UxNTggPSAkKGA8ZGl2IGlkPSJodG1sXzM2MWE2ZmZiOWQzMzQ1OTE4MTVjMTJkNWJlNDdlMTU4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1Mi45MDc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FjZTE2MGJmNjg1YjQzOGU5NzNjZmZmODg3MWNjNDY1LnNldENvbnRlbnQoaHRtbF8zNjFhNmZmYjlkMzM0NTkxODE1YzEyZDViZTQ3ZTE1OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzE5MDBjN2MxNTU2NTRkY2ZiNTZiNzI2MzdkMTBmNjQ5LmJpbmRQb3B1cChwb3B1cF9hY2UxNjBiZjY4NWI0MzhlOTczY2ZmZjg4NzFjYzQ2NSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMTkwMGM3YzE1NTY1NGRjZmI1NmI3MjYzN2QxMGY2NDkuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMDEyODBiYjQ5MDA3NGY0YzhiNzBiN2Q4YzM5YzA3YzMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjQwMywgODEuMTU3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNThhMzlhMGIxM2Q5NDNhOWE2MWNhYzRlNWY5YTgyN2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDUwNjJjNjY4ODVmNDA5MWE3NGJlYjhiMTZkYzJiNDEgPSAkKGA8ZGl2IGlkPSJodG1sX2Q1MDYyYzY2ODg1ZjQwOTFhNzRiZWI4YjE2ZGMyYjQxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNTYuMDA1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81OGEzOWEwYjEzZDk0M2E5YTYxY2FjNGU1ZjlhODI3ZC5zZXRDb250ZW50KGh0bWxfZDUwNjJjNjY4ODVmNDA5MWE3NGJlYjhiMTZkYzJiNDEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8wMTI4MGJiNDkwMDc0ZjRjOGI3MGI3ZDhjMzljMDdjMy5iaW5kUG9wdXAocG9wdXBfNThhMzlhMGIxM2Q5NDNhOWE2MWNhYzRlNWY5YTgyN2QpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzAxMjgwYmI0OTAwNzRmNGM4YjcwYjdkOGMzOWMwN2MzLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzViNzc1NTE5MDA2NDRmMmQ4OWNmZTY4M2I3ZmVjNDMwID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4zOTYsIDgxLjE2OF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFkNjZkNTc5MTJkNTQ3MjZhZTZkZjFjMTJiMjI1NTQzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Y1ZTE3YTdkM2Y1OTQxNmM5MDUwOWU1ZTA2ZDc3YjZjID0gJChgPGRpdiBpZD0iaHRtbF9mNWUxN2E3ZDNmNTk0MTZjOTA1MDllNWUwNmQ3N2I2YyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgNTMuMjM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFkNjZkNTc5MTJkNTQ3MjZhZTZkZjFjMTJiMjI1NTQzLnNldENvbnRlbnQoaHRtbF9mNWUxN2E3ZDNmNTk0MTZjOTA1MDllNWUwNmQ3N2I2Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzViNzc1NTE5MDA2NDRmMmQ4OWNmZTY4M2I3ZmVjNDMwLmJpbmRQb3B1cChwb3B1cF8xZDY2ZDU3OTEyZDU0NzI2YWU2ZGYxYzEyYjIyNTU0MykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNWI3NzU1MTkwMDY0NGYyZDg5Y2ZlNjgzYjdmZWM0MzAuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYTQxZjNjODNkNGRiNDYzYWI4YTJhNWE0MGZkNDRhZWMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjM5NiwgODEuMTY4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjk4OTU4MjM5NTViNDYzNGI5YTNhMjAxMTg2ZDRiNTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGUyMTcwZmMwZmFiNDIzY2IzOTRmOTE5NGM0YjAxN2UgPSAkKGA8ZGl2IGlkPSJodG1sXzBlMjE3MGZjMGZhYjQyM2NiMzk0ZjkxOTRjNGIwMTdlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA1Ni40MTg8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzY5ODk1ODIzOTU1YjQ2MzRiOWEzYTIwMTE4NmQ0YjUyLnNldENvbnRlbnQoaHRtbF8wZTIxNzBmYzBmYWI0MjNjYjM5NGY5MTk0YzRiMDE3ZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2E0MWYzYzgzZDRkYjQ2M2FiOGEyYTVhNDBmZDQ0YWVjLmJpbmRQb3B1cChwb3B1cF82OTg5NTgyMzk1NWI0NjM0YjlhM2EyMDExODZkNGI1MikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYTQxZjNjODNkNGRiNDYzYWI4YTJhNWE0MGZkNDRhZWMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOGExNDQyNDIyZGQxNGU3ODk2OWI5ODU4ODMyYjg0Y2EgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjM5NiwgODEuMTY4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGJiMmVlMzQzNWZjNDBlNmI3MWE5NzE5MTA1ZDA2YTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTM4NWMxNzFjY2YyNGU4M2JiMjk1ZDk0YjE0NDExNDUgPSAkKGA8ZGl2IGlkPSJodG1sXzEzODVjMTcxY2NmMjRlODNiYjI5NWQ5NGIxNDQxMTQ1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1Ny43MjM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RiYjJlZTM0MzVmYzQwZTZiNzFhOTcxOTEwNWQwNmExLnNldENvbnRlbnQoaHRtbF8xMzg1YzE3MWNjZjI0ZTgzYmIyOTVkOTRiMTQ0MTE0NSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzhhMTQ0MjQyMmRkMTRlNzg5NjliOTg1ODgzMmI4NGNhLmJpbmRQb3B1cChwb3B1cF9kYmIyZWUzNDM1ZmM0MGU2YjcxYTk3MTkxMDVkMDZhMSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOGExNDQyNDIyZGQxNGU3ODk2OWI5ODU4ODMyYjg0Y2EuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNTA0NzYxZWNmYjUyNGNjYmFmNzhjMDIxMDc2NzA0ODAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjE5NywgODEuNDI3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTQ1NjEwMmQzZDZiNGMyODk4NTNkOGEzMDNiZGFjNTQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWFjZWIyNDc3NWQ5NGRiOTkxYzMwMTAyZGMzMWUyZjYgPSAkKGA8ZGl2IGlkPSJodG1sX2FhY2ViMjQ3NzVkOTRkYjk5MWMzMDEwMmRjMzFlMmY2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA1NS4zMjI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU0NTYxMDJkM2Q2YjRjMjg5ODUzZDhhMzAzYmRhYzU0LnNldENvbnRlbnQoaHRtbF9hYWNlYjI0Nzc1ZDk0ZGI5OTFjMzAxMDJkYzMxZTJmNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzUwNDc2MWVjZmI1MjRjY2JhZjc4YzAyMTA3NjcwNDgwLmJpbmRQb3B1cChwb3B1cF81NDU2MTAyZDNkNmI0YzI4OTg1M2Q4YTMwM2JkYWM1NCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNTA0NzYxZWNmYjUyNGNjYmFmNzhjMDIxMDc2NzA0ODAuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfODlhMWFlZmIyM2Y0NDk0OGE3NjgzNmRhYWY5ZjljNzggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjE5NywgODEuNDI3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGMxNjExZWM0N2NmNDNiYmFkNGMxMmI2YWE3MmY1MTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjRjOGZmYTc4YWNiNDU4YzliYzkyYTE3YmUwOTc4YmQgPSAkKGA8ZGl2IGlkPSJodG1sXzI0YzhmZmE3OGFjYjQ1OGM5YmM5MmExN2JlMDk3OGJkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQ4LjU2NjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGMxNjExZWM0N2NmNDNiYmFkNGMxMmI2YWE3MmY1MTIuc2V0Q29udGVudChodG1sXzI0YzhmZmE3OGFjYjQ1OGM5YmM5MmExN2JlMDk3OGJkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODlhMWFlZmIyM2Y0NDk0OGE3NjgzNmRhYWY5ZjljNzguYmluZFBvcHVwKHBvcHVwXzhjMTYxMWVjNDdjZjQzYmJhZDRjMTJiNmFhNzJmNTEyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84OWExYWVmYjIzZjQ0OTQ4YTc2ODM2ZGFhZjlmOWM3OC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85OGZjOGI0NzQ0Yzk0NzNkODAyNjQzYWFmYzUzNDdiZCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTk3LCA4MS40MjddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mZmE4OGFiMTVjY2I0YmYyYjI1MDlmOWNkMWEzZmExOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84MDViMTdjNWRhMTY0NTgwODJlZTZmOTY1OTFiYmY2OSA9ICQoYDxkaXYgaWQ9Imh0bWxfODA1YjE3YzVkYTE2NDU4MDgyZWU2Zjk2NTkxYmJmNjkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgNDEuNTY5PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mZmE4OGFiMTVjY2I0YmYyYjI1MDlmOWNkMWEzZmExOS5zZXRDb250ZW50KGh0bWxfODA1YjE3YzVkYTE2NDU4MDgyZWU2Zjk2NTkxYmJmNjkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl85OGZjOGI0NzQ0Yzk0NzNkODAyNjQzYWFmYzUzNDdiZC5iaW5kUG9wdXAocG9wdXBfZmZhODhhYjE1Y2NiNGJmMmIyNTA5ZjljZDFhM2ZhMTkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzk4ZmM4YjQ3NDRjOTQ3M2Q4MDI2NDNhYWZjNTM0N2JkLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2NhMzFjNzRmM2VlNjQ1YjliMGI3MzNiYzcxYWZiZGE2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4xOTEsIDgxLjQzN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzM1OWU3ZDEwOGRjZjRiZTc5ZGVhNmRhMjMzOTBkNjIxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2IxYTBlOWU0M2Y1MDQ2MDE4NWI4MTc4YjA3ZmZiZjdmID0gJChgPGRpdiBpZD0iaHRtbF9iMWEwZTllNDNmNTA0NjAxODViODE3OGIwN2ZmYmY3ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQ3LjAzODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzU5ZTdkMTA4ZGNmNGJlNzlkZWE2ZGEyMzM5MGQ2MjEuc2V0Q29udGVudChodG1sX2IxYTBlOWU0M2Y1MDQ2MDE4NWI4MTc4YjA3ZmZiZjdmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfY2EzMWM3NGYzZWU2NDViOWIwYjczM2JjNzFhZmJkYTYuYmluZFBvcHVwKHBvcHVwXzM1OWU3ZDEwOGRjZjRiZTc5ZGVhNmRhMjMzOTBkNjIxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9jYTMxYzc0ZjNlZTY0NWI5YjBiNzMzYmM3MWFmYmRhNi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl82M2RhNDk2MDkxMzc0NzcyODg0YWVkYzU0NTY0ZDJkNyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTkxLCA4MS40MzddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xMjNjZjUyMWZmOGU0NTUzODcyMzNhYjRhYWMwNjdjYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZTY3NTM3NWI4OTQ0YzIwYTcyYzk5YjNhM2U4MjM1MSA9ICQoYDxkaXYgaWQ9Imh0bWxfZGU2NzUzNzViODk0NGMyMGE3MmM5OWIzYTNlODIzNTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgNDMuOTQxPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xMjNjZjUyMWZmOGU0NTUzODcyMzNhYjRhYWMwNjdjYy5zZXRDb250ZW50KGh0bWxfZGU2NzUzNzViODk0NGMyMGE3MmM5OWIzYTNlODIzNTEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82M2RhNDk2MDkxMzc0NzcyODg0YWVkYzU0NTY0ZDJkNy5iaW5kUG9wdXAocG9wdXBfMTIzY2Y1MjFmZjhlNDU1Mzg3MjMzYWI0YWFjMDY3Y2MpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzYzZGE0OTYwOTEzNzQ3NzI4ODRhZWRjNTQ1NjRkMmQ3LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzg0YWYyNjkyOGM3NDRlYjNiNjA3NDJjMzhiNDJjNDA2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4xOSwgODEuNDM3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTRiOTBhYzZiOWYyNDkwNTlkOWYyNmVhNjcyYzAwMmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDM1YjkwNDFlYzBjNGRlYWJkMmQ5MjYxZDRkZDkzODkgPSAkKGA8ZGl2IGlkPSJodG1sXzAzNWI5MDQxZWMwYzRkZWFiZDJkOTI2MWQ0ZGQ5Mzg5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQ1Ljc3NTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTRiOTBhYzZiOWYyNDkwNTlkOWYyNmVhNjcyYzAwMmYuc2V0Q29udGVudChodG1sXzAzNWI5MDQxZWMwYzRkZWFiZDJkOTI2MWQ0ZGQ5Mzg5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODRhZjI2OTI4Yzc0NGViM2I2MDc0MmMzOGI0MmM0MDYuYmluZFBvcHVwKHBvcHVwXzk0YjkwYWM2YjlmMjQ5MDU5ZDlmMjZlYTY3MmMwMDJmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84NGFmMjY5MjhjNzQ0ZWIzYjYwNzQyYzM4YjQyYzQwNi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zYTFlODUyMGRmN2I0YTQ5YmEwY2Q1YTdiODllY2JiMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTg4LCA4MS40NDFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zZWI1YTQ4MTQ5YzI0YzJmYWFkYWM0Yzg4ZWM4M2ViZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80MWFlZmI5YTViMzE0ZjczOTI3MjhmYzZlZGE3ZDI3ZiA9ICQoYDxkaXYgaWQ9Imh0bWxfNDFhZWZiOWE1YjMxNGY3MzkyNzI4ZmM2ZWRhN2QyN2YiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDUwLjU3NjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfM2ViNWE0ODE0OWMyNGMyZmFhZGFjNGM4OGVjODNlYmUuc2V0Q29udGVudChodG1sXzQxYWVmYjlhNWIzMTRmNzM5MjcyOGZjNmVkYTdkMjdmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfM2ExZTg1MjBkZjdiNGE0OWJhMGNkNWE3Yjg5ZWNiYjIuYmluZFBvcHVwKHBvcHVwXzNlYjVhNDgxNDljMjRjMmZhYWRhYzRjODhlYzgzZWJlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8zYTFlODUyMGRmN2I0YTQ5YmEwY2Q1YTdiODllY2JiMi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85MGM5ZDk3OGQ3NDE0YTQ0OGQwN2ZlNzNiMzIxZTYzOCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTg4LCA4MS40NDFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNTgyNWNiY2ZlMzA0ZDQxYjczZTY3NGJmZDQ4Y2YzYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMzM3YzU5Mjg2Nzg0ZjE5YWE1YjVjZWEwMmNmNTYzNSA9ICQoYDxkaXYgaWQ9Imh0bWxfYTMzN2M1OTI4Njc4NGYxOWFhNWI1Y2VhMDJjZjU2MzUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgMzguMzk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I1ODI1Y2JjZmUzMDRkNDFiNzNlNjc0YmZkNDhjZjNiLnNldENvbnRlbnQoaHRtbF9hMzM3YzU5Mjg2Nzg0ZjE5YWE1YjVjZWEwMmNmNTYzNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzkwYzlkOTc4ZDc0MTRhNDQ4ZDA3ZmU3M2IzMjFlNjM4LmJpbmRQb3B1cChwb3B1cF9iNTgyNWNiY2ZlMzA0ZDQxYjczZTY3NGJmZDQ4Y2YzYikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTBjOWQ5NzhkNzQxNGE0NDhkMDdmZTczYjMyMWU2MzguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZWNjMzk5MDQ1NDMwNDIwYWJjODZlYmUxMmM3OTJlNmMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjE4OCwgODEuNDQxXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTE5MzlhODVlZTQ0NDA5MDhjM2U2ZGNmOGRiY2Y4ZTggPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjgyZTdjNjQ1ODE4NDNjYjlhZDM2MmU4MDczNTAwMDIgPSAkKGA8ZGl2IGlkPSJodG1sX2I4MmU3YzY0NTgxODQzY2I5YWQzNjJlODA3MzUwMDAyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQwLjM0NjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTE5MzlhODVlZTQ0NDA5MDhjM2U2ZGNmOGRiY2Y4ZTguc2V0Q29udGVudChodG1sX2I4MmU3YzY0NTgxODQzY2I5YWQzNjJlODA3MzUwMDAyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZWNjMzk5MDQ1NDMwNDIwYWJjODZlYmUxMmM3OTJlNmMuYmluZFBvcHVwKHBvcHVwX2UxOTM5YTg1ZWU0NDQwOTA4YzNlNmRjZjhkYmNmOGU4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9lY2MzOTkwNDU0MzA0MjBhYmM4NmViZTEyYzc5MmU2Yy5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85NmI5ZjQyZWQ5MGM0ZDU3ODQwMWE4OGE5NmJjYmUzOCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMDE0LCA4MS42NDhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xMDEzMDJlMTBjNDg0YmE5YjJjNjU0ZDAzNDFkYzY2MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85MWI1ODRiYjhiMzg0NTBiODZlMjZmYTZlODAzYWQyYyA9ICQoYDxkaXYgaWQ9Imh0bWxfOTFiNTg0YmI4YjM4NDUwYjg2ZTI2ZmE2ZTgwM2FkMmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEluZGlhbiBIeWJyaWQgMjI4NSwgICBZaWVsZCAzOC43MTk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzEwMTMwMmUxMGM0ODRiYTliMmM2NTRkMDM0MWRjNjYzLnNldENvbnRlbnQoaHRtbF85MWI1ODRiYjhiMzg0NTBiODZlMjZmYTZlODAzYWQyYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzk2YjlmNDJlZDkwYzRkNTc4NDAxYTg4YTk2YmNiZTM4LmJpbmRQb3B1cChwb3B1cF8xMDEzMDJlMTBjNDg0YmE5YjJjNjU0ZDAzNDFkYzY2MykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTZiOWY0MmVkOTBjNGQ1Nzg0MDFhODhhOTZiY2JlMzguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNjM3NmIyN2Q5MzY1NGM1MDk5ZDNlYzRiYzAyZTViOTYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjAxNCwgODEuNjQ4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWUxZDJmZTcxMWEwNGRlMDk0YWFhMDQ2MWFiNWQwNzQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTAxMDZhNWVjZmNmNDA3M2I5ODhmOTJlNTM0ZTJiZmUgPSAkKGA8ZGl2IGlkPSJodG1sXzEwMTA2YTVlY2ZjZjQwNzNiOTg4ZjkyZTUzNGUyYmZlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBJbmRpYW4gSHlicmlkIDIyODUsICAgWWllbGQgMzkuMDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMWUxZDJmZTcxMWEwNGRlMDk0YWFhMDQ2MWFiNWQwNzQuc2V0Q29udGVudChodG1sXzEwMTA2YTVlY2ZjZjQwNzNiOTg4ZjkyZTUzNGUyYmZlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNjM3NmIyN2Q5MzY1NGM1MDk5ZDNlYzRiYzAyZTViOTYuYmluZFBvcHVwKHBvcHVwXzFlMWQyZmU3MTFhMDRkZTA5NGFhYTA0NjFhYjVkMDc0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl82Mzc2YjI3ZDkzNjU0YzUwOTlkM2VjNGJjMDJlNWI5Ni5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85OGZlZDVjYzk4MGU0ZWY3ODI5OTM1NTMzZTNhNDU0ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMDE0LCA4MS42NDhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MTlmNzFjMmE4MmU0MWIxOGVmZDQ5YTg2MWVlNTE5MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMjJhNzdhMGY0NmI0Yjc2OGRhNGY4ZDczMGMxNDRiNCA9ICQoYDxkaXYgaWQ9Imh0bWxfZjIyYTc3YTBmNDZiNGI3NjhkYTRmOGQ3MzBjMTQ0YjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDQ3LjA1MjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTE5ZjcxYzJhODJlNDFiMThlZmQ0OWE4NjFlZTUxOTIuc2V0Q29udGVudChodG1sX2YyMmE3N2EwZjQ2YjRiNzY4ZGE0ZjhkNzMwYzE0NGI0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOThmZWQ1Y2M5ODBlNGVmNzgyOTkzNTUzM2UzYTQ1NGUuYmluZFBvcHVwKHBvcHVwXzUxOWY3MWMyYTgyZTQxYjE4ZWZkNDlhODYxZWU1MTkyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85OGZlZDVjYzk4MGU0ZWY3ODI5OTM1NTMzZTNhNDU0ZS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mMzA2NjQ1NmI0MTY0NjIxYjVkMDhlZTkxODRiZDEzYSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjcuOTk5LCA4MS42NDhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81YmM3OTJiNDkwM2U0OTQzYmIwNmJiODU5YzA5ZDQxYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82YWI0NGRjZTlhMjI0MmVjYTcxMWY2ZDQ1ZjYyYjE3YyA9ICQoYDxkaXYgaWQ9Imh0bWxfNmFiNDRkY2U5YTIyNDJlY2E3MTFmNmQ0NWY2MmIxN2MiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA1Ny4zMDM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzViYzc5MmI0OTAzZTQ5NDNiYjA2YmI4NTljMDlkNDFiLnNldENvbnRlbnQoaHRtbF82YWI0NGRjZTlhMjI0MmVjYTcxMWY2ZDQ1ZjYyYjE3Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2YzMDY2NDU2YjQxNjQ2MjFiNWQwOGVlOTE4NGJkMTNhLmJpbmRQb3B1cChwb3B1cF81YmM3OTJiNDkwM2U0OTQzYmIwNmJiODU5YzA5ZDQxYikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZjMwNjY0NTZiNDE2NDYyMWI1ZDA4ZWU5MTg0YmQxM2EuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZmU3ZTU0YWUzYTY3NDg0ZTg1OWVlNGEwZTBjN2QzYmEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI3Ljk5OSwgODEuNjQ4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNGM0M2Y1ZTg0MDY3NDIxY2I2N2QxNzExYmU0YzkwMzIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWE5NDJjZmQ4MzgwNDNlYWFhZWJkN2U1MzZlNDg5ZmIgPSAkKGA8ZGl2IGlkPSJodG1sX2FhOTQyY2ZkODM4MDQzZWFhYWViZDdlNTM2ZTQ4OWZiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1My4zNDM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRjNDNmNWU4NDA2NzQyMWNiNjdkMTcxMWJlNGM5MDMyLnNldENvbnRlbnQoaHRtbF9hYTk0MmNmZDgzODA0M2VhYWFlYmQ3ZTUzNmU0ODlmYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2ZlN2U1NGFlM2E2NzQ4NGU4NTllZTRhMGUwYzdkM2JhLmJpbmRQb3B1cChwb3B1cF80YzQzZjVlODQwNjc0MjFjYjY3ZDE3MTFiZTRjOTAzMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZmU3ZTU0YWUzYTY3NDg0ZTg1OWVlNGEwZTBjN2QzYmEuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMmFjNzBkY2Y2MTc0NGUyYTlmNzcyYzg1NzRkYjEwOTggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI3Ljk5OSwgODEuNjQ4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDE2OGIwZjI5MGY4NGUyNmJjNDNmMjllMDczZjU1ZDAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDFhNTVhZjJkOGYzNDRlZWJkZTA4YWQyYTIyMjlkOTIgPSAkKGA8ZGl2IGlkPSJodG1sXzQxYTU1YWYyZDhmMzQ0ZWViZGUwOGFkMmEyMjI5ZDkyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1NS40NTY8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQxNjhiMGYyOTBmODRlMjZiYzQzZjI5ZTA3M2Y1NWQwLnNldENvbnRlbnQoaHRtbF80MWE1NWFmMmQ4ZjM0NGVlYmRlMDhhZDJhMjIyOWQ5Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzJhYzcwZGNmNjE3NDRlMmE5Zjc3MmM4NTc0ZGIxMDk4LmJpbmRQb3B1cChwb3B1cF80MTY4YjBmMjkwZjg0ZTI2YmM0M2YyOWUwNzNmNTVkMCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMmFjNzBkY2Y2MTc0NGUyYTlmNzcyYzg1NzRkYjEwOTguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTlhZjhjMjFiMDVmNGYwODk2NmNjNzdmNjk0N2FmYzcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjAwNywgODEuNjQzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjIyOWMyZGY4ZTNjNGM2MmI2MzExNDI0MWY1MGUwOTcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzgyYTEwZmJjZDk4NDI4N2FjYWM5Y2MzOTQ3ZjE3ZDQgPSAkKGA8ZGl2IGlkPSJodG1sXzM4MmExMGZiY2Q5ODQyODdhY2FjOWNjMzk0N2YxN2Q0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNTcuNTA1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82MjI5YzJkZjhlM2M0YzYyYjYzMTE0MjQxZjUwZTA5Ny5zZXRDb250ZW50KGh0bWxfMzgyYTEwZmJjZDk4NDI4N2FjYWM5Y2MzOTQ3ZjE3ZDQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xOWFmOGMyMWIwNWY0ZjA4OTY2Y2M3N2Y2OTQ3YWZjNy5iaW5kUG9wdXAocG9wdXBfNjIyOWMyZGY4ZTNjNGM2MmI2MzExNDI0MWY1MGUwOTcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzE5YWY4YzIxYjA1ZjRmMDg5NjZjYzc3ZjY5NDdhZmM3LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzI3ZjUxZGRiMTg3MzQzODZhNzc5YTEzYmM3N2EyOTA0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4wMDcsIDgxLjY0Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk0NjU4YmM4OTU3YjQ4NTRiMzRlMGRjZDJkNzIzOTM5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E2M2MxMjdlYWVlOTQ2NGE5NmVkZGMxZDc0NmY2MWY2ID0gJChgPGRpdiBpZD0iaHRtbF9hNjNjMTI3ZWFlZTk0NjRhOTZlZGRjMWQ3NDZmNjFmNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDYwLjk4NTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTQ2NThiYzg5NTdiNDg1NGIzNGUwZGNkMmQ3MjM5Mzkuc2V0Q29udGVudChodG1sX2E2M2MxMjdlYWVlOTQ2NGE5NmVkZGMxZDc0NmY2MWY2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMjdmNTFkZGIxODczNDM4NmE3NzlhMTNiYzc3YTI5MDQuYmluZFBvcHVwKHBvcHVwXzk0NjU4YmM4OTU3YjQ4NTRiMzRlMGRjZDJkNzIzOTM5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8yN2Y1MWRkYjE4NzM0Mzg2YTc3OWExM2JjNzdhMjkwNC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mNzZhMmRkNDAxMzA0OTdiOTEwMGQ5MmYxOTA4YmQzMSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTAzLCA4MS41MzJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84MmQyYmFmZmFlZGI0MjU2YjhmOTViMDUzODI1ZTlhYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zMjk2OWQ5MjViMTA0OGE5YTcyM2EyYzA2NDBhNzRmNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMzI5NjlkOTI1YjEwNDhhOWE3MjNhMmMwNjQwYTc0ZjUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDU2LjQ0MTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODJkMmJhZmZhZWRiNDI1NmI4Zjk1YjA1MzgyNWU5YWIuc2V0Q29udGVudChodG1sXzMyOTY5ZDkyNWIxMDQ4YTlhNzIzYTJjMDY0MGE3NGY1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZjc2YTJkZDQwMTMwNDk3YjkxMDBkOTJmMTkwOGJkMzEuYmluZFBvcHVwKHBvcHVwXzgyZDJiYWZmYWVkYjQyNTZiOGY5NWIwNTM4MjVlOWFiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9mNzZhMmRkNDAxMzA0OTdiOTEwMGQ5MmYxOTA4YmQzMS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84ODE4MDQwMTM0ZWI0YTcxYTczMmFmMGI2YjMwNzUwMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTAzLCA4MS41MzFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82MGNhMDRlNWQ2MTU0ZTkyYTRhMDMzZDAxMjVhMmVmZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xOTJlYzRmNWRhNzE0M2NjYjljMTc5ZTNmYTFjOTRiNiA9ICQoYDxkaXYgaWQ9Imh0bWxfMTkyZWM0ZjVkYTcxNDNjY2I5YzE3OWUzZmExYzk0YjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgNTIuNTY1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82MGNhMDRlNWQ2MTU0ZTkyYTRhMDMzZDAxMjVhMmVmZC5zZXRDb250ZW50KGh0bWxfMTkyZWM0ZjVkYTcxNDNjY2I5YzE3OWUzZmExYzk0YjYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84ODE4MDQwMTM0ZWI0YTcxYTczMmFmMGI2YjMwNzUwMi5iaW5kUG9wdXAocG9wdXBfNjBjYTA0ZTVkNjE1NGU5MmE0YTAzM2QwMTI1YTJlZmQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzg4MTgwNDAxMzRlYjRhNzFhNzMyYWYwYjZiMzA3NTAyLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzkzYmUwNGVkNWFlMDRhOWI5Nzk2ZGM0ZWIxZjkwZmU4ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC4xMDMsIDgxLjUzMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRkOWM0MzlhNTBhZTQzYjViMzYxMjc2OGUzMDY1MmQwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc3MzVjMGM1NDgyMzQyY2M4MmRmODkyZTAxNjBlMTQwID0gJChgPGRpdiBpZD0iaHRtbF83NzM1YzBjNTQ4MjM0MmNjODJkZjg5MmUwMTYwZTE0MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVW5rbm93biwgICBZaWVsZCA1Mi45MTQ8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRkOWM0MzlhNTBhZTQzYjViMzYxMjc2OGUzMDY1MmQwLnNldENvbnRlbnQoaHRtbF83NzM1YzBjNTQ4MjM0MmNjODJkZjg5MmUwMTYwZTE0MCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzkzYmUwNGVkNWFlMDRhOWI5Nzk2ZGM0ZWIxZjkwZmU4LmJpbmRQb3B1cChwb3B1cF80ZDljNDM5YTUwYWU0M2I1YjM2MTI3NjhlMzA2NTJkMCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTNiZTA0ZWQ1YWUwNGE5Yjk3OTZkYzRlYjFmOTBmZTguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMzNjMzkwNzQxOTkxNGIzMjkyODlhZTQ4YjQ1ZDc0NzcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExMiwgODEuNTE5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTZkM2U2OTJiYjhlNGY4OGI1ZTNjMmIyN2NjYzY5NGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOTMyOTA3MTc0MDE0NGE3Zjk0ZTU0ZGU3MmZlNTA2MzAgPSAkKGA8ZGl2IGlkPSJodG1sXzkzMjkwNzE3NDAxNDRhN2Y5NGU1NGRlNzJmZTUwNjMwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA1MS41Mjc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E2ZDNlNjkyYmI4ZTRmODhiNWUzYzJiMjdjY2M2OTRmLnNldENvbnRlbnQoaHRtbF85MzI5MDcxNzQwMTQ0YTdmOTRlNTRkZTcyZmU1MDYzMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzMzYzM5MDc0MTk5MTRiMzI5Mjg5YWU0OGI0NWQ3NDc3LmJpbmRQb3B1cChwb3B1cF9hNmQzZTY5MmJiOGU0Zjg4YjVlM2MyYjI3Y2NjNjk0ZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMzNjMzkwNzQxOTkxNGIzMjkyODlhZTQ4YjQ1ZDc0NzcuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYzViMjExYTU1NTVkNGY3NmE2YjIxNzgzZmVkNmI3ZGIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExMiwgODEuNTE5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTRiMzg1YjFiZmM3NGQ5OWE2OTg3MGQyNTVkNTNkNTcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjhhOGJhZjJkMzc4NDc0MGE5NTgyOTNhNjhhN2JkOTcgPSAkKGA8ZGl2IGlkPSJodG1sX2I4YThiYWYyZDM3ODQ3NDBhOTU4MjkzYTY4YTdiZDk3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQ3LjQ3ODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMTRiMzg1YjFiZmM3NGQ5OWE2OTg3MGQyNTVkNTNkNTcuc2V0Q29udGVudChodG1sX2I4YThiYWYyZDM3ODQ3NDBhOTU4MjkzYTY4YTdiZDk3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYzViMjExYTU1NTVkNGY3NmE2YjIxNzgzZmVkNmI3ZGIuYmluZFBvcHVwKHBvcHVwXzE0YjM4NWIxYmZjNzRkOTlhNjk4NzBkMjU1ZDUzZDU3KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9jNWIyMTFhNTU1NWQ0Zjc2YTZiMjE3ODNmZWQ2YjdkYi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85Y2Q0MjYwYzM4MDA0MGUxYmU3MDEyYTMxMmJjNTQ0OCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguMTEyLCA4MS41MTldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xYjNmZTBjYmY2NmQ0Yjg0OWJjNzZiMGYwY2ZlZjljYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84OWFkYzgyODZlMWM0NWFjYWI4NzQ4ZjAzZDIyMTYzZSA9ICQoYDxkaXYgaWQ9Imh0bWxfODlhZGM4Mjg2ZTFjNDVhY2FiODc0OGYwM2QyMjE2M2UiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFVua25vd24sICAgWWllbGQgNTEuNjQ8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFiM2ZlMGNiZjY2ZDRiODQ5YmM3NmIwZjBjZmVmOWNhLnNldENvbnRlbnQoaHRtbF84OWFkYzgyODZlMWM0NWFjYWI4NzQ4ZjAzZDIyMTYzZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzljZDQyNjBjMzgwMDQwZTFiZTcwMTJhMzEyYmM1NDQ4LmJpbmRQb3B1cChwb3B1cF8xYjNmZTBjYmY2NmQ0Yjg0OWJjNzZiMGYwY2ZlZjljYSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOWNkNDI2MGMzODAwNDBlMWJlNzAxMmEzMTJiYzU0NDguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYWM1MmJkNTJmMDM2NDJiYWIxMjM2MmY3ZDFiMGY2MTkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExNiwgODEuNTA5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODRlMDIyNGMzOWIwNDhjZjg3YmJiNzdlNjQyZTY1OTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTc1YjVjMmQ1MGU5NGVmZjg2ZGQ3Nzc0MWUwNTFjZGQgPSAkKGA8ZGl2IGlkPSJodG1sXzE3NWI1YzJkNTBlOTRlZmY4NmRkNzc3NDFlMDUxY2RkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDkuMzY8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzg0ZTAyMjRjMzliMDQ4Y2Y4N2JiYjc3ZTY0MmU2NTkxLnNldENvbnRlbnQoaHRtbF8xNzViNWMyZDUwZTk0ZWZmODZkZDc3NzQxZTA1MWNkZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2FjNTJiZDUyZjAzNjQyYmFiMTIzNjJmN2QxYjBmNjE5LmJpbmRQb3B1cChwb3B1cF84NGUwMjI0YzM5YjA0OGNmODdiYmI3N2U2NDJlNjU5MSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYWM1MmJkNTJmMDM2NDJiYWIxMjM2MmY3ZDFiMGY2MTkuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmJlZTczNWIyZmU0NDBiZjgzMzY4ZDM4OWIyODEwMzIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExNiwgODEuNTA5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzJmYzFhNTE2ZGU0NDcxNmJjNjBmYjI4ODU5YjIxYzQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDI1ZWY2NDJhOWY5NDRiZmIyOTI5NjkwNjA2ZGRiZTMgPSAkKGA8ZGl2IGlkPSJodG1sXzAyNWVmNjQyYTlmOTQ0YmZiMjkyOTY5MDYwNmRkYmUzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDQ2Ljc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzcyZmMxYTUxNmRlNDQ3MTZiYzYwZmIyODg1OWIyMWM0LnNldENvbnRlbnQoaHRtbF8wMjVlZjY0MmE5Zjk0NGJmYjI5Mjk2OTA2MDZkZGJlMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzZiZWU3MzViMmZlNDQwYmY4MzM2OGQzODliMjgxMDMyLmJpbmRQb3B1cChwb3B1cF83MmZjMWE1MTZkZTQ0NzE2YmM2MGZiMjg4NTliMjFjNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNmJlZTczNWIyZmU0NDBiZjgzMzY4ZDM4OWIyODEwMzIuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmUzMmEyYTYzNDg0NDMxM2IwZWJjN2FjNDI5ZmZjMzEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExNiwgODEuNTA5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzZlMjJkNjc3MDRhNDYxNmI5ZjUwOWJhZmQ5OTMyZDIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNmZiY2ZlMDNiZjFiNGYzOTg5MzkyMDBjYjk4YzcyZDAgPSAkKGA8ZGl2IGlkPSJodG1sXzZmYmNmZTAzYmYxYjRmMzk4OTM5MjAwY2I5OGM3MmQwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBVbmtub3duLCAgIFlpZWxkIDM3LjkwODwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzZlMjJkNjc3MDRhNDYxNmI5ZjUwOWJhZmQ5OTMyZDIuc2V0Q29udGVudChodG1sXzZmYmNmZTAzYmYxYjRmMzk4OTM5MjAwY2I5OGM3MmQwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNmUzMmEyYTYzNDg0NDMxM2IwZWJjN2FjNDI5ZmZjMzEuYmluZFBvcHVwKHBvcHVwXzc2ZTIyZDY3NzA0YTQ2MTZiOWY1MDliYWZkOTkzMmQyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl82ZTMyYTJhNjM0ODQ0MzEzYjBlYmM3YWM0MjlmZmMzMS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iOTEyNTBhYmMxZTk0ZjI4OGYxZDUxYTcwYTUyYjAyMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTUsIDgxLjA2MV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Y1YWJmZWFlMzg2MjRhYTQ4MWZlMzhjZDU1YzcwNmZiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQ5OTA5MzA1ODkzMjQyMWZhNWRiZmVkMWE2OWRhZGNlID0gJChgPGRpdiBpZD0iaHRtbF80OTkwOTMwNTg5MzI0MjFmYTVkYmZlZDFhNjlkYWRjZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQ0LjEyPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mNWFiZmVhZTM4NjI0YWE0ODFmZTM4Y2Q1NWM3MDZmYi5zZXRDb250ZW50KGh0bWxfNDk5MDkzMDU4OTMyNDIxZmE1ZGJmZWQxYTY5ZGFkY2UpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9iOTEyNTBhYmMxZTk0ZjI4OGYxZDUxYTcwYTUyYjAyMi5iaW5kUG9wdXAocG9wdXBfZjVhYmZlYWUzODYyNGFhNDgxZmUzOGNkNTVjNzA2ZmIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2I5MTI1MGFiYzFlOTRmMjg4ZjFkNTFhNzBhNTJiMDIyLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzUwZThmNzhjMjgzYzRjMTlhODJiNWYxNDEyZDA4Zjk0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC41NSwgODEuMDYyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTg4NDM3ZWIzMDE3NDlmMWFlMTkzNDJiZmVkZWUwMTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOTUxNzU3ZGQxY2VhNGQ0NGFlYzYwOWM5MWZkMDgxNjEgPSAkKGA8ZGl2IGlkPSJodG1sXzk1MTc1N2RkMWNlYTRkNDRhZWM2MDljOTFmZDA4MTYxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDQuNTI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2U4ODQzN2ViMzAxNzQ5ZjFhZTE5MzQyYmZlZGVlMDEyLnNldENvbnRlbnQoaHRtbF85NTE3NTdkZDFjZWE0ZDQ0YWVjNjA5YzkxZmQwODE2MSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzUwZThmNzhjMjgzYzRjMTlhODJiNWYxNDEyZDA4Zjk0LmJpbmRQb3B1cChwb3B1cF9lODg0MzdlYjMwMTc0OWYxYWUxOTM0MmJmZWRlZTAxMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNTBlOGY3OGMyODNjNGMxOWE4MmI1ZjE0MTJkMDhmOTQuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOGNjZDQ4NDJlOTUxNGQzYTgwN2Y4YjU4NjNlN2ZkNjAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjU1LCA4MS4wNjJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82ODAzNzU3NWRkYTY0NTY0YTY5YTRiYTJhZDZiOWI2MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yOTk5MDFkZjBiOTg0M2VjOWZmMjBlMjBmOTYzM2E3NiA9ICQoYDxkaXYgaWQ9Imh0bWxfMjk5OTAxZGYwYjk4NDNlYzlmZjIwZTIwZjk2MzNhNzYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEFkaXR5YSwgICBZaWVsZCA0NS4wNjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjgwMzc1NzVkZGE2NDU2NGE2OWE0YmEyYWQ2YjliNjIuc2V0Q29udGVudChodG1sXzI5OTkwMWRmMGI5ODQzZWM5ZmYyMGUyMGY5NjMzYTc2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOGNjZDQ4NDJlOTUxNGQzYTgwN2Y4YjU4NjNlN2ZkNjAuYmluZFBvcHVwKHBvcHVwXzY4MDM3NTc1ZGRhNjQ1NjRhNjlhNGJhMmFkNmI5YjYyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84Y2NkNDg0MmU5NTE0ZDNhODA3ZjhiNTg2M2U3ZmQ2MC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80YjkxMDc1YjVjYTA0NTQzYWE0M2NmNGE4MDIxNWFkOCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ1LCA4MS4wNjNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82MThhZWIzZWNiZGY0N2ZkODQ4MGZiZWEwZjAyMDczNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMjY5ZTczM2VmNGY0MzQ4YWQxNGQxMzBkZjJjZjFmZiA9ICQoYDxkaXYgaWQ9Imh0bWxfYTI2OWU3MzNlZjRmNDM0OGFkMTRkMTMwZGYyY2YxZmYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA1MS40NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjE4YWViM2VjYmRmNDdmZDg0ODBmYmVhMGYwMjA3MzUuc2V0Q29udGVudChodG1sX2EyNjllNzMzZWY0ZjQzNDhhZDE0ZDEzMGRmMmNmMWZmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNGI5MTA3NWI1Y2EwNDU0M2FhNDNjZjRhODAyMTVhZDguYmluZFBvcHVwKHBvcHVwXzYxOGFlYjNlY2JkZjQ3ZmQ4NDgwZmJlYTBmMDIwNzM1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl80YjkxMDc1YjVjYTA0NTQzYWE0M2NmNGE4MDIxNWFkOC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81MWE5MjA1YzIxYmM0ZGQwOWVlZjMxNmJhMjg3NGNkMSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ1LCA4MS4wNjNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kMjNhZWNhYTY3N2U0ODAxOWEyOWIxM2QxNzlhN2I0NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82YTE2MmY2MGVkYzE0MGY3OGQ3ZTNkZDJjMjRjODkwNCA9ICQoYDxkaXYgaWQ9Imh0bWxfNmExNjJmNjBlZGMxNDBmNzhkN2UzZGQyYzI0Yzg5MDQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEFkaXR5YSwgICBZaWVsZCA0OS4wNjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDIzYWVjYWE2NzdlNDgwMTlhMjliMTNkMTc5YTdiNDYuc2V0Q29udGVudChodG1sXzZhMTYyZjYwZWRjMTQwZjc4ZDdlM2RkMmMyNGM4OTA0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNTFhOTIwNWMyMWJjNGRkMDllZWYzMTZiYTI4NzRjZDEuYmluZFBvcHVwKHBvcHVwX2QyM2FlY2FhNjc3ZTQ4MDE5YTI5YjEzZDE3OWE3YjQ2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81MWE5MjA1YzIxYmM0ZGQwOWVlZjMxNmJhMjg3NGNkMS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jZWM0MzQ1N2FiMWI0YjNjYWY4N2RhZjRlYmJhZTAyYiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ1LCA4MS4wNjNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mMDU1YTVjNDUxOTc0YjUzOTYwNTZlZmUwMTA4NDgzMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yODczOTQyNTM3Nzk0OTEzODJmZjJlNGIyNmZhM2UyNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjg3Mzk0MjUzNzc5NDkxMzgyZmYyZTRiMjZmYTNlMjUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEFkaXR5YSwgICBZaWVsZCA0Ny40NDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjA1NWE1YzQ1MTk3NGI1Mzk2MDU2ZWZlMDEwODQ4MzAuc2V0Q29udGVudChodG1sXzI4NzM5NDI1Mzc3OTQ5MTM4MmZmMmU0YjI2ZmEzZTI1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfY2VjNDM0NTdhYjFiNGIzY2FmODdkYWY0ZWJiYWUwMmIuYmluZFBvcHVwKHBvcHVwX2YwNTVhNWM0NTE5NzRiNTM5NjA1NmVmZTAxMDg0ODMwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9jZWM0MzQ1N2FiMWI0YjNjYWY4N2RhZjRlYmJhZTAyYi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81MjQxODEzNDgxM2I0Zjk2ODI0MGE4NzZiMWE2NGFmMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ3LCA4MS4wNjZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kOTEyYjRlYzlmOWQ0YTc5ODY1NTMyZWQ1Y2Q0YjQ4YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kOTdhYjhmNzNmZmE0OWY1OTA0ODU2N2UwOTRiMjFmNSA9ICQoYDxkaXYgaWQ9Imh0bWxfZDk3YWI4ZjczZmZhNDlmNTkwNDg1NjdlMDk0YjIxZjUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0Ny42NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDkxMmI0ZWM5ZjlkNGE3OTg2NTUzMmVkNWNkNGI0OGIuc2V0Q29udGVudChodG1sX2Q5N2FiOGY3M2ZmYTQ5ZjU5MDQ4NTY3ZTA5NGIyMWY1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNTI0MTgxMzQ4MTNiNGY5NjgyNDBhODc2YjFhNjRhZjIuYmluZFBvcHVwKHBvcHVwX2Q5MTJiNGVjOWY5ZDRhNzk4NjU1MzJlZDVjZDRiNDhiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81MjQxODEzNDgxM2I0Zjk2ODI0MGE4NzZiMWE2NGFmMi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9hNDlhZjZiMjJjMGQ0MzA2YWU3MDI5OTc5MWIwZTJmMyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ3LCA4MS4wNjZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MzZhYjA3MzVjODk0MjY0YWFlOWFhMzhkYWU1OWQ4YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82OTM4MTY0ODYxNmQ0MzdmODRkMzVjZmJlNzJhNTIxMSA9ICQoYDxkaXYgaWQ9Imh0bWxfNjkzODE2NDg2MTZkNDM3Zjg0ZDM1Y2ZiZTcyYTUyMTEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0Ni42NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTM2YWIwNzM1Yzg5NDI2NGFhZTlhYTM4ZGFlNTlkOGIuc2V0Q29udGVudChodG1sXzY5MzgxNjQ4NjE2ZDQzN2Y4NGQzNWNmYmU3MmE1MjExKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYTQ5YWY2YjIyYzBkNDMwNmFlNzAyOTk3OTFiMGUyZjMuYmluZFBvcHVwKHBvcHVwXzUzNmFiMDczNWM4OTQyNjRhYWU5YWEzOGRhZTU5ZDhiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9hNDlhZjZiMjJjMGQ0MzA2YWU3MDI5OTc5MWIwZTJmMy5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl83NzE2NGEzZjc5MWM0NzUzYjY0MjgzMDFhNTgzNGExMCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNTQ3LCA4MS4wNjZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jODg1ZTkyYjZkNGI0YWRiODEzOWE3OTNmOGRiYjJlYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82ZTNkMWQ2Y2JhNzg0MjJlOWVjZjA1MTU2Zjg5N2QzZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNmUzZDFkNmNiYTc4NDIyZTllY2YwNTE1NmY4OTdkM2QiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0My43MzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzg4NWU5MmI2ZDRiNGFkYjgxMzlhNzkzZjhkYmIyZWEuc2V0Q29udGVudChodG1sXzZlM2QxZDZjYmE3ODQyMmU5ZWNmMDUxNTZmODk3ZDNkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNzcxNjRhM2Y3OTFjNDc1M2I2NDI4MzAxYTU4MzRhMTAuYmluZFBvcHVwKHBvcHVwX2M4ODVlOTJiNmQ0YjRhZGI4MTM5YTc5M2Y4ZGJiMmVhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl83NzE2NGEzZjc5MWM0NzUzYjY0MjgzMDFhNTgzNGExMC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84NjNmODgzZDEwMDA0YmNjOTY4ZTE4Y2MxZDc0ODdjYSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjQyLCA4MS4xM10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzlmYTFiY2Y5M2NkYjQzN2VhNDY5ZTg2NDczYjViZWMwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzkwYTUwOTgxN2NhOTRmMDQ5MjRlMzY5ZWZkYzZhNmZlID0gJChgPGRpdiBpZD0iaHRtbF85MGE1MDk4MTdjYTk0ZjA0OTI0ZTM2OWVmZGM2YTZmZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQ3LjQ0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85ZmExYmNmOTNjZGI0MzdlYTQ2OWU4NjQ3M2I1YmVjMC5zZXRDb250ZW50KGh0bWxfOTBhNTA5ODE3Y2E5NGYwNDkyNGUzNjllZmRjNmE2ZmUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84NjNmODgzZDEwMDA0YmNjOTY4ZTE4Y2MxZDc0ODdjYS5iaW5kUG9wdXAocG9wdXBfOWZhMWJjZjkzY2RiNDM3ZWE0NjllODY0NzNiNWJlYzApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzg2M2Y4ODNkMTAwMDRiY2M5NjhlMThjYzFkNzQ4N2NhLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2E4M2UxMWQ2ZjY5NTQ2ZWNiZjY5MTE1YzRkZDUzY2Y3ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42NDIsIDgxLjEzMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2IxZjIyZmYyOTA1YTQ4M2M4NjhlM2RkYjM1OGVkMGE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhkY2FkOTAxZGM2YjQ1MTg4YjFhZGMyMzAwYWMxODVmID0gJChgPGRpdiBpZD0iaHRtbF84ZGNhZDkwMWRjNmI0NTE4OGIxYWRjMjMwMGFjMTg1ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNTUuNTc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2IxZjIyZmYyOTA1YTQ4M2M4NjhlM2RkYjM1OGVkMGE0LnNldENvbnRlbnQoaHRtbF84ZGNhZDkwMWRjNmI0NTE4OGIxYWRjMjMwMGFjMTg1Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2E4M2UxMWQ2ZjY5NTQ2ZWNiZjY5MTE1YzRkZDUzY2Y3LmJpbmRQb3B1cChwb3B1cF9iMWYyMmZmMjkwNWE0ODNjODY4ZTNkZGIzNThlZDBhNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYTgzZTExZDZmNjk1NDZlY2JmNjkxMTVjNGRkNTNjZjcuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMWUzMGE1NTY0ZDU2NGVjM2IzNDk3M2EyNTgxMjhkZGIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjY0MiwgODEuMTMxXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTFkNzJiN2E3NTE1NDY5ZDgwNDYwOGM3NjNmZTZjOTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjA2ODAwZDE4NWU0NDdkNWJjOGM5MzI4ZjdjOWYyOGEgPSAkKGA8ZGl2IGlkPSJodG1sXzIwNjgwMGQxODVlNDQ3ZDViYzhjOTMyOGY3YzlmMjhhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1NC4wMzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTFkNzJiN2E3NTE1NDY5ZDgwNDYwOGM3NjNmZTZjOTEuc2V0Q29udGVudChodG1sXzIwNjgwMGQxODVlNDQ3ZDViYzhjOTMyOGY3YzlmMjhhKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMWUzMGE1NTY0ZDU2NGVjM2IzNDk3M2EyNTgxMjhkZGIuYmluZFBvcHVwKHBvcHVwXzUxZDcyYjdhNzUxNTQ2OWQ4MDQ2MDhjNzYzZmU2YzkxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8xZTMwYTU1NjRkNTY0ZWMzYjM0OTczYTI1ODEyOGRkYi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iYTY1NjA2ODc2NDE0M2Y4YWU3ZDRhMDJhOTE1YzIxYSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjM5LCA4MS4xMjZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85OTZiZjNhMGIxMDg0NGZiOGEwZGYwYWYzZDg5M2Y3ZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82ODFkMTgwNjNmOWQ0YTgwYmFlZDgzNTVjNzE4MDhmNyA9ICQoYDxkaXYgaWQ9Imh0bWxfNjgxZDE4MDYzZjlkNGE4MGJhZWQ4MzU1YzcxODA4ZjciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0OC4yMzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTk2YmYzYTBiMTA4NDRmYjhhMGRmMGFmM2Q4OTNmN2Quc2V0Q29udGVudChodG1sXzY4MWQxODA2M2Y5ZDRhODBiYWVkODM1NWM3MTgwOGY3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYmE2NTYwNjg3NjQxNDNmOGFlN2Q0YTAyYTkxNWMyMWEuYmluZFBvcHVwKHBvcHVwXzk5NmJmM2EwYjEwODQ0ZmI4YTBkZjBhZjNkODkzZjdkKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9iYTY1NjA2ODc2NDE0M2Y4YWU3ZDRhMDJhOTE1YzIxYS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl83ZTA4MmUzMWMyNzE0ZWQ1YWIwYmUzM2M0NzNlZGYxMCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjM5LCA4MS4xMjZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80NDUzZWRlODk1YTc0MmFhODQ4ZjhiNGEyYjkxNzkyYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jODNlYjc4NzYzNmI0OWY3YjVjYThhMDM1N2E5NjY2YiA9ICQoYDxkaXYgaWQ9Imh0bWxfYzgzZWI3ODc2MzZiNDlmN2I1Y2E4YTAzNTdhOTY2NmIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDUyLjg0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NDUzZWRlODk1YTc0MmFhODQ4ZjhiNGEyYjkxNzkyYy5zZXRDb250ZW50KGh0bWxfYzgzZWI3ODc2MzZiNDlmN2I1Y2E4YTAzNTdhOTY2NmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83ZTA4MmUzMWMyNzE0ZWQ1YWIwYmUzM2M0NzNlZGYxMC5iaW5kUG9wdXAocG9wdXBfNDQ1M2VkZTg5NWE3NDJhYTg0OGY4YjRhMmI5MTc5MmMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzdlMDgyZTMxYzI3MTRlZDVhYjBiZTMzYzQ3M2VkZjEwLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2UyZWM3MjA4ZGNmNzRlNGI4MGViYjNhNmU3N2RjODMwID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42MzksIDgxLjEyNl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjMTcyMDI4MmY4MjQzNDVhMzE5MmRiZDI5OWNmZTMxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzliMzg4ZjRiODA3MzQzMGZiMWJiYTg2MzNjZGI2NjNlID0gJChgPGRpdiBpZD0iaHRtbF85YjM4OGY0YjgwNzM0MzBmYjFiYmE4NjMzY2RiNjYzZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNTQuNTg8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2ZjMTcyMDI4MmY4MjQzNDVhMzE5MmRiZDI5OWNmZTMxLnNldENvbnRlbnQoaHRtbF85YjM4OGY0YjgwNzM0MzBmYjFiYmE4NjMzY2RiNjYzZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2UyZWM3MjA4ZGNmNzRlNGI4MGViYjNhNmU3N2RjODMwLmJpbmRQb3B1cChwb3B1cF9mYzE3MjAyODJmODI0MzQ1YTMxOTJkYmQyOTljZmUzMSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZTJlYzcyMDhkY2Y3NGU0YjgwZWJiM2E2ZTc3ZGM4MzAuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOGQwMGUzZjA5NzJmNDYyZmFiYzhkY2Y0MjY0ODYwMzUgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYzOCwgODEuMTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wMzYwZjJlNDlhNTA0MGFmYWZiMWNmNTBjODgzYWQ5ZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83NzM0MWUwMzkzOTE0MWU4YjRmYjBmZjZjYzAxYzg3OCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzczNDFlMDM5MzkxNDFlOGI0ZmIwZmY2Y2MwMWM4NzgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCAzNy42NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDM2MGYyZTQ5YTUwNDBhZmFmYjFjZjUwYzg4M2FkOWYuc2V0Q29udGVudChodG1sXzc3MzQxZTAzOTM5MTQxZThiNGZiMGZmNmNjMDFjODc4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOGQwMGUzZjA5NzJmNDYyZmFiYzhkY2Y0MjY0ODYwMzUuYmluZFBvcHVwKHBvcHVwXzAzNjBmMmU0OWE1MDQwYWZhZmIxY2Y1MGM4ODNhZDlmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84ZDAwZTNmMDk3MmY0NjJmYWJjOGRjZjQyNjQ4NjAzNS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iNGNmYWNmZDlhOGI0ZDNmOGMwOTExYTQyMTg0MDQ3ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjM4LCA4MS4xM10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU0Mjc3MTUwYjk1OTQ0ODE4NmViNTJlZDU4YzNjMDI2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ExZjQyODA4ZmUxMDQyMTY5ZTRhNmJkMmRmZDg4YWRkID0gJChgPGRpdiBpZD0iaHRtbF9hMWY0MjgwOGZlMTA0MjE2OWU0YTZiZDJkZmQ4OGFkZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDMuNTU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU0Mjc3MTUwYjk1OTQ0ODE4NmViNTJlZDU4YzNjMDI2LnNldENvbnRlbnQoaHRtbF9hMWY0MjgwOGZlMTA0MjE2OWU0YTZiZDJkZmQ4OGFkZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2I0Y2ZhY2ZkOWE4YjRkM2Y4YzA5MTFhNDIxODQwNDdlLmJpbmRQb3B1cChwb3B1cF81NDI3NzE1MGI5NTk0NDgxODZlYjUyZWQ1OGMzYzAyNikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYjRjZmFjZmQ5YThiNGQzZjhjMDkxMWE0MjE4NDA0N2UuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZjE5MGFkNzdjZDY0NGE5ZDljMThmYjAxN2I3NTYwOTMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYzOCwgODEuMTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kZTY1ZDI4NzkyMjA0NTY1OTExZDVlMzllZjZlZDJkZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wZmI5OWJjMDJmODQ0ODRkYTI4MDllOTQwNzgwMGIxZSA9ICQoYDxkaXYgaWQ9Imh0bWxfMGZiOTliYzAyZjg0NDg0ZGEyODA5ZTk0MDc4MDBiMWUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ0Ljg3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kZTY1ZDI4NzkyMjA0NTY1OTExZDVlMzllZjZlZDJkZS5zZXRDb250ZW50KGh0bWxfMGZiOTliYzAyZjg0NDg0ZGEyODA5ZTk0MDc4MDBiMWUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9mMTkwYWQ3N2NkNjQ0YTlkOWMxOGZiMDE3Yjc1NjA5My5iaW5kUG9wdXAocG9wdXBfZGU2NWQyODc5MjIwNDU2NTkxMWQ1ZTM5ZWY2ZWQyZGUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2YxOTBhZDc3Y2Q2NDRhOWQ5YzE4ZmIwMTdiNzU2MDkzLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2ExOTAwYmVkYzk0YzQ5OTY5NWRmZDY4ZmEwNTMyY2RhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42MzgsIDgxLjEzMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZmNGU4OGViNTc1NzQ1YmY4OGNhMDRmYWQ1MTI4MmE2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzFmM2FkNTU5NmZiZjRiZGM5YjM5YTA5OWU1ZTIwMjZlID0gJChgPGRpdiBpZD0iaHRtbF8xZjNhZDU1OTZmYmY0YmRjOWIzOWEwOTllNWUyMDI2ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDUxLjc3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82ZjRlODhlYjU3NTc0NWJmODhjYTA0ZmFkNTEyODJhNi5zZXRDb250ZW50KGh0bWxfMWYzYWQ1NTk2ZmJmNGJkYzliMzlhMDk5ZTVlMjAyNmUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9hMTkwMGJlZGM5NGM0OTk2OTVkZmQ2OGZhMDUzMmNkYS5iaW5kUG9wdXAocG9wdXBfNmY0ZTg4ZWI1NzU3NDViZjg4Y2EwNGZhZDUxMjgyYTYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2ExOTAwYmVkYzk0YzQ5OTY5NWRmZDY4ZmEwNTMyY2RhLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzQ4YzNlYzEyNGM4ZjQ3YTNhZTlkY2VjNjJhNzQ2Y2U2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42MzgsIDgxLjEzMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I5YWM4MzA5Mjg0NDRjMWY5NWJjYmU4MmIyOWFmOTY1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzA2MTMwYjBjMjY5ZTQyMTZiYzNiYmY5ZmZkN2E3MzRkID0gJChgPGRpdiBpZD0iaHRtbF8wNjEzMGIwYzI2OWU0MjE2YmMzYmJmOWZmZDdhNzM0ZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDguMDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjlhYzgzMDkyODQ0NGMxZjk1YmNiZTgyYjI5YWY5NjUuc2V0Q29udGVudChodG1sXzA2MTMwYjBjMjY5ZTQyMTZiYzNiYmY5ZmZkN2E3MzRkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNDhjM2VjMTI0YzhmNDdhM2FlOWRjZWM2MmE3NDZjZTYuYmluZFBvcHVwKHBvcHVwX2I5YWM4MzA5Mjg0NDRjMWY5NWJjYmU4MmIyOWFmOTY1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl80OGMzZWMxMjRjOGY0N2EzYWU5ZGNlYzYyYTc0NmNlNi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jYzc1MGQyNmU0Nzk0ZWFmYmQ1YzMxNmM3MGQxNzZmZiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzIyLCA4MC44MzRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80YzdiYTU1ZWJhNGU0MTY3OTY0NTRmOTlhOTFmYzVlYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wNzRmMWQwZjllMTE0ZjVmYWJjYzE4M2NkNzMyNWY1NCA9ICQoYDxkaXYgaWQ9Imh0bWxfMDc0ZjFkMGY5ZTExNGY1ZmFiY2MxODNjZDczMjVmNTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA1My44MzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGM3YmE1NWViYTRlNDE2Nzk2NDU0Zjk5YTkxZmM1ZWIuc2V0Q29udGVudChodG1sXzA3NGYxZDBmOWUxMTRmNWZhYmNjMTgzY2Q3MzI1ZjU0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfY2M3NTBkMjZlNDc5NGVhZmJkNWMzMTZjNzBkMTc2ZmYuYmluZFBvcHVwKHBvcHVwXzRjN2JhNTVlYmE0ZTQxNjc5NjQ1NGY5OWE5MWZjNWViKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9jYzc1MGQyNmU0Nzk0ZWFmYmQ1YzMxNmM3MGQxNzZmZi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8xNDdiOWM0MjUyZGI0ZmFkYWZhNmEzNjQ5YWUxMmVmYyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzIyLCA4MC44MzRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80MDg5YTZhZDQ4MWI0ODY5OGExYmMxNGU4YTZiZTkyMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83MTBkOTcwYWIzNmU0MmYwOWJhMGYyNzZjY2VhNTJmMSA9ICQoYDxkaXYgaWQ9Imh0bWxfNzEwZDk3MGFiMzZlNDJmMDliYTBmMjc2Y2NlYTUyZjEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ1Ljg3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80MDg5YTZhZDQ4MWI0ODY5OGExYmMxNGU4YTZiZTkyMy5zZXRDb250ZW50KGh0bWxfNzEwZDk3MGFiMzZlNDJmMDliYTBmMjc2Y2NlYTUyZjEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xNDdiOWM0MjUyZGI0ZmFkYWZhNmEzNjQ5YWUxMmVmYy5iaW5kUG9wdXAocG9wdXBfNDA4OWE2YWQ0ODFiNDg2OThhMWJjMTRlOGE2YmU5MjMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzE0N2I5YzQyNTJkYjRmYWRhZmE2YTM2NDlhZTEyZWZjLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzY5MDlmMWFhNzM0NzRiZmQ4OTA1MDdlOWJjMmFjZjU1ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43MjIsIDgwLjgzNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzA1ZTAzMDU1MDg3ZTRkYWY4YWMzMjg4NzgxODUzMmE2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzkzOGY1NDM2MTQ2YTQxMDZiMzM3MjI2MDU1YzdjNmQyID0gJChgPGRpdiBpZD0iaHRtbF85MzhmNTQzNjE0NmE0MTA2YjMzNzIyNjA1NWM3YzZkMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDEuNDc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzA1ZTAzMDU1MDg3ZTRkYWY4YWMzMjg4NzgxODUzMmE2LnNldENvbnRlbnQoaHRtbF85MzhmNTQzNjE0NmE0MTA2YjMzNzIyNjA1NWM3YzZkMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzY5MDlmMWFhNzM0NzRiZmQ4OTA1MDdlOWJjMmFjZjU1LmJpbmRQb3B1cChwb3B1cF8wNWUwMzA1NTA4N2U0ZGFmOGFjMzI4ODc4MTg1MzJhNikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNjkwOWYxYWE3MzQ3NGJmZDg5MDUwN2U5YmMyYWNmNTUuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZTk1NWI0ODVmNDM0NGRlZGE2OWVkNTBhZjVlMDEzYjcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjcyNywgODAuODI4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2JlMTE1ZjVmN2JlNGJlMGEwZDQ3ODc4ODkzODA2ODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGViOGVlMjU4YzUzNDc2MmIxY2NhYjllYTA2YWJmNWYgPSAkKGA8ZGl2IGlkPSJodG1sXzRlYjhlZTI1OGM1MzQ3NjJiMWNjYWI5ZWEwNmFiZjVmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNTAuNTY8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2NiZTExNWY1ZjdiZTRiZTBhMGQ0Nzg3ODg5MzgwNjgwLnNldENvbnRlbnQoaHRtbF80ZWI4ZWUyNThjNTM0NzYyYjFjY2FiOWVhMDZhYmY1Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2U5NTViNDg1ZjQzNDRkZWRhNjllZDUwYWY1ZTAxM2I3LmJpbmRQb3B1cChwb3B1cF9jYmUxMTVmNWY3YmU0YmUwYTBkNDc4Nzg4OTM4MDY4MCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZTk1NWI0ODVmNDM0NGRlZGE2OWVkNTBhZjVlMDEzYjcuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTIwNWJjZDVkYjMyNGI3Mzg2OWNkNDhkMTE4ZDY0NzIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjcyNywgODAuODI4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMGU4ODJiYjI5N2FjNDUxYjlhM2RmZmRhZmQ1MmRlZmEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTZjMDE4YTQ1ODA3NDZhMTk0MGUxZTY3MDYxNzM0YzMgPSAkKGA8ZGl2IGlkPSJodG1sX2U2YzAxOGE0NTgwNzQ2YTE5NDBlMWU2NzA2MTczNGMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1OC41MzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGU4ODJiYjI5N2FjNDUxYjlhM2RmZmRhZmQ1MmRlZmEuc2V0Q29udGVudChodG1sX2U2YzAxOGE0NTgwNzQ2YTE5NDBlMWU2NzA2MTczNGMzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMTIwNWJjZDVkYjMyNGI3Mzg2OWNkNDhkMTE4ZDY0NzIuYmluZFBvcHVwKHBvcHVwXzBlODgyYmIyOTdhYzQ1MWI5YTNkZmZkYWZkNTJkZWZhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8xMjA1YmNkNWRiMzI0YjczODY5Y2Q0OGQxMThkNjQ3Mi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yMTc1MGRjNDJlZDU0ZGNkYmQ5YjA2YmUxMmM3OWI4YyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzI3LCA4MC44MjhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYzg2ZjRjODQ1ZTg0MDZkYmJiMjlmZjNiZmNjNThiYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lN2EzN2M4OTIzYTE0NDJjODViMjIwMjdlNGMyMDM3NCA9ICQoYDxkaXYgaWQ9Imh0bWxfZTdhMzdjODkyM2ExNDQyYzg1YjIyMDI3ZTRjMjAzNzQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDU2Ljc5PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kYzg2ZjRjODQ1ZTg0MDZkYmJiMjlmZjNiZmNjNThiYy5zZXRDb250ZW50KGh0bWxfZTdhMzdjODkyM2ExNDQyYzg1YjIyMDI3ZTRjMjAzNzQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8yMTc1MGRjNDJlZDU0ZGNkYmQ5YjA2YmUxMmM3OWI4Yy5iaW5kUG9wdXAocG9wdXBfZGM4NmY0Yzg0NWU4NDA2ZGJiYjI5ZmYzYmZjYzU4YmMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzIxNzUwZGM0MmVkNTRkY2RiZDliMDZiZTEyYzc5YjhjLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzc0NTViOTgyNzUyNDRmOTVhMzFjMzRjYjZkOGZkZmU3ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43NDEsIDgwLjgzOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E1OWIwZWUzOTI3NjQzNDE4N2Q5N2M0ODRjNWNjMmNhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzgxMTNmMDUyODVhODRmMzRhMDhjOTY0Yjg0M2MyNzA1ID0gJChgPGRpdiBpZD0iaHRtbF84MTEzZjA1Mjg1YTg0ZjM0YTA4Yzk2NGI4NDNjMjcwNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTkwgOTcxLCAgIFlpZWxkIDQzLjgyPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hNTliMGVlMzkyNzY0MzQxODdkOTdjNDg0YzVjYzJjYS5zZXRDb250ZW50KGh0bWxfODExM2YwNTI4NWE4NGYzNGEwOGM5NjRiODQzYzI3MDUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83NDU1Yjk4Mjc1MjQ0Zjk1YTMxYzM0Y2I2ZDhmZGZlNy5iaW5kUG9wdXAocG9wdXBfYTU5YjBlZTM5Mjc2NDM0MTg3ZDk3YzQ4NGM1Y2MyY2EpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzc0NTViOTgyNzUyNDRmOTVhMzFjMzRjYjZkOGZkZmU3LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzA0ZjI5ZDA5MTgxMDRhNzE5M2I0MzQ4OGJjN2I5MDMzID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43NDEsIDgwLjgzOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzEyMDZiZWRkZTRkZTRiMDY5MTY0MGYxMWY1ZDdhODMyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM1YTA3ZTVjZjdhMDRjYjVhNTc4ZDY5NTBkMWFmM2U0ID0gJChgPGRpdiBpZD0iaHRtbF8zNWEwN2U1Y2Y3YTA0Y2I1YTU3OGQ2OTUwZDFhZjNlNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgNTIuNzI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzEyMDZiZWRkZTRkZTRiMDY5MTY0MGYxMWY1ZDdhODMyLnNldENvbnRlbnQoaHRtbF8zNWEwN2U1Y2Y3YTA0Y2I1YTU3OGQ2OTUwZDFhZjNlNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzA0ZjI5ZDA5MTgxMDRhNzE5M2I0MzQ4OGJjN2I5MDMzLmJpbmRQb3B1cChwb3B1cF8xMjA2YmVkZGU0ZGU0YjA2OTE2NDBmMTFmNWQ3YTgzMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMDRmMjlkMDkxODEwNGE3MTkzYjQzNDg4YmM3YjkwMzMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfODMxNTNlMjllNDgzNGI3M2FmNDBjZjI5M2I5YzJjMmYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljc0MSwgODAuODM5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTJmY2U1Njc5OGY1NGMxNWFlMDdkMzExNDVjM2RmZTggPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjdjZWM2N2QwMTVjNDljZjlkNDJkNjFmN2Y4ZTE3MzMgPSAkKGA8ZGl2IGlkPSJodG1sX2I3Y2VjNjdkMDE1YzQ5Y2Y5ZDQyZDYxZjdmOGUxNzMzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1Mi43NjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTJmY2U1Njc5OGY1NGMxNWFlMDdkMzExNDVjM2RmZTguc2V0Q29udGVudChodG1sX2I3Y2VjNjdkMDE1YzQ5Y2Y5ZDQyZDYxZjdmOGUxNzMzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODMxNTNlMjllNDgzNGI3M2FmNDBjZjI5M2I5YzJjMmYuYmluZFBvcHVwKHBvcHVwX2UyZmNlNTY3OThmNTRjMTVhZTA3ZDMxMTQ1YzNkZmU4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84MzE1M2UyOWU0ODM0YjczYWY0MGNmMjkzYjljMmMyZi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iYzU4MzU5ZDQwMzg0Y2M1YjgwNGI0MjI5Y2U0YTdjOSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjI1LCA4MC44MTFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xYzc5MzkxOTAwN2M0ODdiODQzYzYzYTNiMTZhZmQ4OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iNWVhZDU2YjZhM2Y0Y2YwOTg2YzA5MGUxZGE3ZGQyNiA9ICQoYDxkaXYgaWQ9Imh0bWxfYjVlYWQ1NmI2YTNmNGNmMDk4NmMwOTBlMWRhN2RkMjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDQ1LjI4PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xYzc5MzkxOTAwN2M0ODdiODQzYzYzYTNiMTZhZmQ4OC5zZXRDb250ZW50KGh0bWxfYjVlYWQ1NmI2YTNmNGNmMDk4NmMwOTBlMWRhN2RkMjYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9iYzU4MzU5ZDQwMzg0Y2M1YjgwNGI0MjI5Y2U0YTdjOS5iaW5kUG9wdXAocG9wdXBfMWM3OTM5MTkwMDdjNDg3Yjg0M2M2M2EzYjE2YWZkODgpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2JjNTgzNTlkNDAzODRjYzViODA0YjQyMjljZTRhN2M5LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzNlZmUwODZiODUwNDRiNmJhMWRiZjQ0OTE3NzEwNjJmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42MjUsIDgwLjgxMl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VlNDg3OTY4NDA0MjRmMjdiZTRmOWNjY2VjYTQ3OGUyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2EzZTAxMjdjOWFiMTRmZDQ4MDg3ZTEzZDM2OTFhYWI4ID0gJChgPGRpdiBpZD0iaHRtbF9hM2UwMTI3YzlhYjE0ZmQ0ODA4N2UxM2QzNjkxYWFiOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgNDQuMzc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2VlNDg3OTY4NDA0MjRmMjdiZTRmOWNjY2VjYTQ3OGUyLnNldENvbnRlbnQoaHRtbF9hM2UwMTI3YzlhYjE0ZmQ0ODA4N2UxM2QzNjkxYWFiOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzNlZmUwODZiODUwNDRiNmJhMWRiZjQ0OTE3NzEwNjJmLmJpbmRQb3B1cChwb3B1cF9lZTQ4Nzk2ODQwNDI0ZjI3YmU0ZjljY2NlY2E0NzhlMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfM2VmZTA4NmI4NTA0NGI2YmExZGJmNDQ5MTc3MTA2MmYuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMzQ1MTY5MzBjMTMzNGUzY2EyMmY5NDZkMjc0Mjg1NDAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYyNSwgODAuODEyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTI0NzBmZWEwNzhjNDRlNjgzOWZmNjM2ODA1ZmE5ZjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTllMzgzZWNjMjViNGJjYTg5MGZhOWMzOTVlZDk3YzggPSAkKGA8ZGl2IGlkPSJodG1sX2U5ZTM4M2VjYzI1YjRiY2E4OTBmYTljMzk1ZWQ5N2M4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA0NC4yOTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTI0NzBmZWEwNzhjNDRlNjgzOWZmNjM2ODA1ZmE5ZjQuc2V0Q29udGVudChodG1sX2U5ZTM4M2VjYzI1YjRiY2E4OTBmYTljMzk1ZWQ5N2M4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMzQ1MTY5MzBjMTMzNGUzY2EyMmY5NDZkMjc0Mjg1NDAuYmluZFBvcHVwKHBvcHVwX2UyNDcwZmVhMDc4YzQ0ZTY4MzlmZjYzNjgwNWZhOWY0KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl8zNDUxNjkzMGMxMzM0ZTNjYTIyZjk0NmQyNzQyODU0MC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80YzAyZjIwYmU2YTE0ZTJlODUxNGQ5MGU5OGQ5NjI0MyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjAzLCA4MC44MTVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83Zjc3MWE4MTRhZTY0MDdiYWY5YWE4NjNhMjE3ZjMyOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83NmRmMjg4OWZkMjc0NzMzOWU3OTQ4YTc1N2IzZTg1ZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNzZkZjI4ODlmZDI3NDczMzllNzk0OGE3NTdiM2U4NWQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDU2LjU1PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83Zjc3MWE4MTRhZTY0MDdiYWY5YWE4NjNhMjE3ZjMyOS5zZXRDb250ZW50KGh0bWxfNzZkZjI4ODlmZDI3NDczMzllNzk0OGE3NTdiM2U4NWQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80YzAyZjIwYmU2YTE0ZTJlODUxNGQ5MGU5OGQ5NjI0My5iaW5kUG9wdXAocG9wdXBfN2Y3NzFhODE0YWU2NDA3YmFmOWFhODYzYTIxN2YzMjkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzRjMDJmMjBiZTZhMTRlMmU4NTE0ZDkwZTk4ZDk2MjQzLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzZmOTBjNTNmMGUxYTQ2OGNiYjA2NDcwN2ZjZDFjNWRjID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42MDMsIDgwLjgxNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQwZTBjMzk2YmY5ZjRmNjQ5ZDJkYjRiODU5OWMzYjM0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzZjY2NhNGFkNzkyYjQ4MDk4NTM2ZDA5N2JjODUwOWRiID0gJChgPGRpdiBpZD0iaHRtbF82Y2NjYTRhZDc5MmI0ODA5ODUzNmQwOTdiYzg1MDlkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgMzUuMzY8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQwZTBjMzk2YmY5ZjRmNjQ5ZDJkYjRiODU5OWMzYjM0LnNldENvbnRlbnQoaHRtbF82Y2NjYTRhZDc5MmI0ODA5ODUzNmQwOTdiYzg1MDlkYik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzZmOTBjNTNmMGUxYTQ2OGNiYjA2NDcwN2ZjZDFjNWRjLmJpbmRQb3B1cChwb3B1cF80MGUwYzM5NmJmOWY0ZjY0OWQyZGI0Yjg1OTljM2IzNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNmY5MGM1M2YwZTFhNDY4Y2JiMDY0NzA3ZmNkMWM1ZGMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOWY4ZDljY2NlZjk1NDE3YzkxODA0NDMyNmYxZmZjNzkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYwMywgODAuODE0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTg2NGE5NjYwZDQ2NDQzYjlkMzk0N2VmNTU3NzBlMmIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjA4N2UwYzNiMDg5NGVkMGIzMmM4NmJhN2ZkODhjZjAgPSAkKGA8ZGl2IGlkPSJodG1sXzIwODdlMGMzYjA4OTRlZDBiMzJjODZiYTdmZDg4Y2YwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCAzNy43NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTg2NGE5NjYwZDQ2NDQzYjlkMzk0N2VmNTU3NzBlMmIuc2V0Q29udGVudChodG1sXzIwODdlMGMzYjA4OTRlZDBiMzJjODZiYTdmZDg4Y2YwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOWY4ZDljY2NlZjk1NDE3YzkxODA0NDMyNmYxZmZjNzkuYmluZFBvcHVwKHBvcHVwX2U4NjRhOTY2MGQ0NjQ0M2I5ZDM5NDdlZjU1NzcwZTJiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85ZjhkOWNjY2VmOTU0MTdjOTE4MDQ0MzI2ZjFmZmM3OS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81MjRhMzMxOGZmOTI0ZTgyOWM1YmU2N2I2NTc4YmFjZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjc0LCA4MC4zNjRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kMmE1ZGU3OGIyY2M0MTViODViNmEwYjhhODZkYzFhMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wZjAxOWFjNTExMTk0MTg0OGIyNWM1MmRjN2E1OTBlNyA9ICQoYDxkaXYgaWQ9Imh0bWxfMGYwMTlhYzUxMTE5NDE4NDhiMjVjNTJkYzdhNTkwZTciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA1MC4xNzg8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QyYTVkZTc4YjJjYzQxNWI4NWI2YTBiOGE4NmRjMWEyLnNldENvbnRlbnQoaHRtbF8wZjAxOWFjNTExMTk0MTg0OGIyNWM1MmRjN2E1OTBlNyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzUyNGEzMzE4ZmY5MjRlODI5YzViZTY3YjY1NzhiYWNlLmJpbmRQb3B1cChwb3B1cF9kMmE1ZGU3OGIyY2M0MTViODViNmEwYjhhODZkYzFhMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNTI0YTMzMThmZjkyNGU4MjljNWJlNjdiNjU3OGJhY2UuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZTRjMGI4OTQxY2Q0NGQwMjkxNTI3NWNlNmNhZDkxY2YgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjY3NCwgODAuMzYzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDE1OGJiZjk5YmVkNGZjZmE0YTRiMGM4ZjQwODk2ODAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNWUyNTkxYTU0MzIzNDY5YzlmNmNjMWUxNjEwYmQyNTIgPSAkKGA8ZGl2IGlkPSJodG1sXzVlMjU5MWE1NDMyMzQ2OWM5ZjZjYzFlMTYxMGJkMjUyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1MS4yNzU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QxNThiYmY5OWJlZDRmY2ZhNGE0YjBjOGY0MDg5NjgwLnNldENvbnRlbnQoaHRtbF81ZTI1OTFhNTQzMjM0NjljOWY2Y2MxZTE2MTBiZDI1Mik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2U0YzBiODk0MWNkNDRkMDI5MTUyNzVjZTZjYWQ5MWNmLmJpbmRQb3B1cChwb3B1cF9kMTU4YmJmOTliZWQ0ZmNmYTRhNGIwYzhmNDA4OTY4MCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZTRjMGI4OTQxY2Q0NGQwMjkxNTI3NWNlNmNhZDkxY2YuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZjFkYzBjZTc0MTg5NDQ1YTgwODg3NzE4NmU4ODE4ZWUgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjY3NCwgODAuMzYzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjUyMTBjMWI4ZmMwNDgxZmE5YzVkZGZlMDhkMzZiY2IgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmEzOWU3MWVjZGU2NDhlZWE1MzhmZDk0NThmYjFhZWQgPSAkKGA8ZGl2IGlkPSJodG1sX2JhMzllNzFlY2RlNjQ4ZWVhNTM4ZmQ5NDU4ZmIxYWVkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA0Ny43NzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjUyMTBjMWI4ZmMwNDgxZmE5YzVkZGZlMDhkMzZiY2Iuc2V0Q29udGVudChodG1sX2JhMzllNzFlY2RlNjQ4ZWVhNTM4ZmQ5NDU4ZmIxYWVkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZjFkYzBjZTc0MTg5NDQ1YTgwODg3NzE4NmU4ODE4ZWUuYmluZFBvcHVwKHBvcHVwXzY1MjEwYzFiOGZjMDQ4MWZhOWM1ZGRmZTA4ZDM2YmNiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9mMWRjMGNlNzQxODk0NDVhODA4ODc3MTg2ZTg4MThlZS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85MjZlZTQzMzBhMzM0ZTcyYmM4ODZlM2UwYjk4OGEwMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjc1LCA4MC4zNzFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mMmQ5YzA4ODYyYTY0ZDMzYWY5ZDZlNTIwY2JlZDIzOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kNDhmNDRiNmM0OWY0OGIwYTRkMmM4NWQwZTFhNTliOCA9ICQoYDxkaXYgaWQ9Imh0bWxfZDQ4ZjQ0YjZjNDlmNDhiMGE0ZDJjODVkMGUxYTU5YjgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEJhbmdhbmdhLCAgIFlpZWxkIDUyLjYzMTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZjJkOWMwODg2MmE2NGQzM2FmOWQ2ZTUyMGNiZWQyMzkuc2V0Q29udGVudChodG1sX2Q0OGY0NGI2YzQ5ZjQ4YjBhNGQyYzg1ZDBlMWE1OWI4KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOTI2ZWU0MzMwYTMzNGU3MmJjODg2ZTNlMGI5ODhhMDIuYmluZFBvcHVwKHBvcHVwX2YyZDljMDg4NjJhNjRkMzNhZjlkNmU1MjBjYmVkMjM5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl85MjZlZTQzMzBhMzM0ZTcyYmM4ODZlM2UwYjk4OGEwMi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81Yjc1NTAyMGEzYzA0MTFmOGFkMTZmMzlhYjU0N2M3ZiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjc1LCA4MC4zNzFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wYTY4OGQzNTJlZmQ0ZDg2YTFlYWNjYzNlNDMzZTJmNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zOGIzMDFkN2ZjZGM0YmM3ODI1OWI4NWM0OTIzOTNmNCA9ICQoYDxkaXYgaWQ9Imh0bWxfMzhiMzAxZDdmY2RjNGJjNzgyNTliODVjNDkyMzkzZjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDQ0LjUxMTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGE2ODhkMzUyZWZkNGQ4NmExZWFjY2MzZTQzM2UyZjYuc2V0Q29udGVudChodG1sXzM4YjMwMWQ3ZmNkYzRiYzc4MjU5Yjg1YzQ5MjM5M2Y0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNWI3NTUwMjBhM2MwNDExZjhhZDE2ZjM5YWI1NDdjN2YuYmluZFBvcHVwKHBvcHVwXzBhNjg4ZDM1MmVmZDRkODZhMWVhY2NjM2U0MzNlMmY2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81Yjc1NTAyMGEzYzA0MTFmOGFkMTZmMzlhYjU0N2M3Zi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jZGQwNjk1NDBkMmQ0MjhlODY5NmRlNTU3ZjEwYzNiMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjc1LCA4MC4zN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzEzOTA4NTQxMzM1MTRlYjM5YTM1ZTMwYTkyZmY5ZTI1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE0NDZlY2UxOGY1MDQxY2U4OGE1MDIwYmM1NmJlYTgwID0gJChgPGRpdiBpZD0iaHRtbF8xNDQ2ZWNlMThmNTA0MWNlODhhNTAyMGJjNTZiZWE4MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgNDYuNDE3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xMzkwODU0MTMzNTE0ZWIzOWEzNWUzMGE5MmZmOWUyNS5zZXRDb250ZW50KGh0bWxfMTQ0NmVjZTE4ZjUwNDFjZTg4YTUwMjBiYzU2YmVhODApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9jZGQwNjk1NDBkMmQ0MjhlODY5NmRlNTU3ZjEwYzNiMi5iaW5kUG9wdXAocG9wdXBfMTM5MDg1NDEzMzUxNGViMzlhMzVlMzBhOTJmZjllMjUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2NkZDA2OTU0MGQyZDQyOGU4Njk2ZGU1NTdmMTBjM2IyLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2QyNTczZGQwNGI4NjQ5NjA5NWUyNWVjOGU4YTY1NGE0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42ODMsIDgwLjM2OF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRjMDdlZDMyYWM4ZTQ4ZDFiMDQ0NGQxY2UzMDBiZjM1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2QxMGIzZWQyYmUxMzRiMWNhZDE3NzBhZjgzNGZmNmI3ID0gJChgPGRpdiBpZD0iaHRtbF9kMTBiM2VkMmJlMTM0YjFjYWQxNzcwYWY4MzRmZjZiNyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogR2F1dGFtLCAgIFlpZWxkIDQ5LjAyNDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGMwN2VkMzJhYzhlNDhkMWIwNDQ0ZDFjZTMwMGJmMzUuc2V0Q29udGVudChodG1sX2QxMGIzZWQyYmUxMzRiMWNhZDE3NzBhZjgzNGZmNmI3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZDI1NzNkZDA0Yjg2NDk2MDk1ZTI1ZWM4ZThhNjU0YTQuYmluZFBvcHVwKHBvcHVwXzRjMDdlZDMyYWM4ZTQ4ZDFiMDQ0NGQxY2UzMDBiZjM1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl9kMjU3M2RkMDRiODY0OTYwOTVlMjVlYzhlOGE2NTRhNC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iNGFmZDZjZDYyNzA0ZWQwOGVmNDQ5ODBlYjU0Njc2MCA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjgzLCA4MC4zNjddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kNzk0OGExMDIxMDQ0MjgxOTE0MDVmYzI3Yzg0YzBjZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NTZlYjYyZjdkOGM0MTFlYTRjN2FlN2Y2YjBlZWMzZCA9ICQoYDxkaXYgaWQ9Imh0bWxfNjU2ZWI2MmY3ZDhjNDExZWE0YzdhZTdmNmIwZWVjM2QiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IEdhdXRhbSwgICBZaWVsZCAzNy4wMDM8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Q3OTQ4YTEwMjEwNDQyODE5MTQwNWZjMjdjODRjMGNkLnNldENvbnRlbnQoaHRtbF82NTZlYjYyZjdkOGM0MTFlYTRjN2FlN2Y2YjBlZWMzZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2I0YWZkNmNkNjI3MDRlZDA4ZWY0NDk4MGViNTQ2NzYwLmJpbmRQb3B1cChwb3B1cF9kNzk0OGExMDIxMDQ0MjgxOTE0MDVmYzI3Yzg0YzBjZCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfYjRhZmQ2Y2Q2MjcwNGVkMDhlZjQ0OTgwZWI1NDY3NjAuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOWRlMDZhYTNlZjZkNDRlZmJlMjIzYTQ1MGViNjk4ZmYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjY4NCwgODAuMzY3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTZhNTBmMWUyZDQ0NGUzZmE0ZGE0N2JmNTdkZTcwNjMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmU0OWFkNzdmNGMzNDA2Zjk3YjI2MGQ2NTRmNmQ3YzYgPSAkKGA8ZGl2IGlkPSJodG1sXzJlNDlhZDc3ZjRjMzQwNmY5N2IyNjBkNjU0ZjZkN2M2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgMzUuNjc3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xNmE1MGYxZTJkNDQ0ZTNmYTRkYTQ3YmY1N2RlNzA2My5zZXRDb250ZW50KGh0bWxfMmU0OWFkNzdmNGMzNDA2Zjk3YjI2MGQ2NTRmNmQ3YzYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl85ZGUwNmFhM2VmNmQ0NGVmYmUyMjNhNDUwZWI2OThmZi5iaW5kUG9wdXAocG9wdXBfMTZhNTBmMWUyZDQ0NGUzZmE0ZGE0N2JmNTdkZTcwNjMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzlkZTA2YWEzZWY2ZDQ0ZWZiZTIyM2E0NTBlYjY5OGZmLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzQ1MThjMzY1MTE0NzQ3YmE5MGM1ZDA5M2I4YmU0Zjc0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43MDMsIDgwLjQyMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzcwOTcwOTMyNTRkMDQ5Nzc5YzM2MjlhYzEwZDE2MGVhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2U3OGE1ZjQ0YTUwNDRmMzRiOTdmMGE1Yjg1MTQ2NThlID0gJChgPGRpdiBpZD0iaHRtbF9lNzhhNWY0NGE1MDQ0ZjM0Yjk3ZjBhNWI4NTE0NjU4ZSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDkuNjU8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzcwOTcwOTMyNTRkMDQ5Nzc5YzM2MjlhYzEwZDE2MGVhLnNldENvbnRlbnQoaHRtbF9lNzhhNWY0NGE1MDQ0ZjM0Yjk3ZjBhNWI4NTE0NjU4ZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzQ1MThjMzY1MTE0NzQ3YmE5MGM1ZDA5M2I4YmU0Zjc0LmJpbmRQb3B1cChwb3B1cF83MDk3MDkzMjU0ZDA0OTc3OWMzNjI5YWMxMGQxNjBlYSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNDUxOGMzNjUxMTQ3NDdiYTkwYzVkMDkzYjhiZTRmNzQuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNTUzYmM4YjBmNmI3NDYxODhkMjQ2ZTA5MDZjZDE4MzUgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjcwMywgODAuNDIyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzk1YTlhZDI4OGUzNDViYjgxNjdlYjg3ZDI2NjhhY2EgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNWRiMGFiZTlkNzk4NDJiNGExMzcyNzk5MjIyYmY3MTkgPSAkKGA8ZGl2IGlkPSJodG1sXzVkYjBhYmU5ZDc5ODQyYjRhMTM3Mjc5OTIyMmJmNzE5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1Mi41MjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzk1YTlhZDI4OGUzNDViYjgxNjdlYjg3ZDI2NjhhY2Euc2V0Q29udGVudChodG1sXzVkYjBhYmU5ZDc5ODQyYjRhMTM3Mjc5OTIyMmJmNzE5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNTUzYmM4YjBmNmI3NDYxODhkMjQ2ZTA5MDZjZDE4MzUuYmluZFBvcHVwKHBvcHVwX2M5NWE5YWQyODhlMzQ1YmI4MTY3ZWI4N2QyNjY4YWNhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81NTNiYzhiMGY2Yjc0NjE4OGQyNDZlMDkwNmNkMTgzNS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81ZTkwOTE1OGZiODM0NWQ4OWQzMDg3NDIyMjg2NDU3ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzAzLCA4MC40MjJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jN2Y5NjAwYjY1ZGM0ZTVlOWRlZWU1NDkxODA5NjViZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wYjIyNjFhNjc0NjA0MDQxOTYwYTMzZjM0MDFlYjhmNiA9ICQoYDxkaXYgaWQ9Imh0bWxfMGIyMjYxYTY3NDYwNDA0MTk2MGEzM2YzNDAxZWI4ZjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0OS4zMzwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzdmOTYwMGI2NWRjNGU1ZTlkZWVlNTQ5MTgwOTY1YmQuc2V0Q29udGVudChodG1sXzBiMjI2MWE2NzQ2MDQwNDE5NjBhMzNmMzQwMWViOGY2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNWU5MDkxNThmYjgzNDVkODlkMzA4NzQyMjI4NjQ1N2UuYmluZFBvcHVwKHBvcHVwX2M3Zjk2MDBiNjVkYzRlNWU5ZGVlZTU0OTE4MDk2NWJkKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81ZTkwOTE1OGZiODM0NWQ4OWQzMDg3NDIyMjg2NDU3ZS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84N2E3ZGI2NDZkZjA0NDY3YjAxMzdkMTUyN2NlMDc0ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzA1LCA4MC40MDddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mM2EyOGU1NWI5ODQ0OTg4YjVjYTI1M2M0YWRkNjZiYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80ODk4YTE4ZjI1YTU0NGRhYjZmOGQ4NGI0MzA1NjgxOCA9ICQoYDxkaXYgaWQ9Imh0bWxfNDg5OGExOGYyNWE1NDRkYWI2ZjhkODRiNDMwNTY4MTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDUwLjIzPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mM2EyOGU1NWI5ODQ0OTg4YjVjYTI1M2M0YWRkNjZiYS5zZXRDb250ZW50KGh0bWxfNDg5OGExOGYyNWE1NDRkYWI2ZjhkODRiNDMwNTY4MTgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84N2E3ZGI2NDZkZjA0NDY3YjAxMzdkMTUyN2NlMDc0ZS5iaW5kUG9wdXAocG9wdXBfZjNhMjhlNTViOTg0NDk4OGI1Y2EyNTNjNGFkZDY2YmEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzg3YTdkYjY0NmRmMDQ0NjdiMDEzN2QxNTI3Y2UwNzRlLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzE0ZmY3MzFkNjYwZjQ4YWZiNjZiMjViOTQ3NjEwYTU4ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43MDYsIDgwLjQwN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzNmOTQ4ODQ0MTUwNzRjMDM4YWNkZGNhNjRiMDU4OGRiID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZjMDAxZGMyOTJhNDQzMDk4ODc0MjlmOTZkYzQ2NGRmID0gJChgPGRpdiBpZD0iaHRtbF9mYzAwMWRjMjkyYTQ0MzA5ODg3NDI5Zjk2ZGM0NjRkZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDQuODg8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzNmOTQ4ODQ0MTUwNzRjMDM4YWNkZGNhNjRiMDU4OGRiLnNldENvbnRlbnQoaHRtbF9mYzAwMWRjMjkyYTQ0MzA5ODg3NDI5Zjk2ZGM0NjRkZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzE0ZmY3MzFkNjYwZjQ4YWZiNjZiMjViOTQ3NjEwYTU4LmJpbmRQb3B1cChwb3B1cF8zZjk0ODg0NDE1MDc0YzAzOGFjZGRjYTY0YjA1ODhkYikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMTRmZjczMWQ2NjBmNDhhZmI2NmIyNWI5NDc2MTBhNTguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfODIzZWFmNmJhYzQwNDMyOWFlNzM5ZTE0OTUyMmNiYzIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjcwNiwgODAuNDA3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWI5YTY1OGY0YTkwNDY5MWE1NjAxZjc5NmRkNTAzN2YgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYWYwM2ZhZjVjNTkzNDk2Y2EzNTcxMDNjOTZkNDAxMDkgPSAkKGA8ZGl2IGlkPSJodG1sX2FmMDNmYWY1YzU5MzQ5NmNhMzU3MTAzYzk2ZDQwMTA5IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDYuNDk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FiOWE2NThmNGE5MDQ2OTFhNTYwMWY3OTZkZDUwMzdmLnNldENvbnRlbnQoaHRtbF9hZjAzZmFmNWM1OTM0OTZjYTM1NzEwM2M5NmQ0MDEwOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzgyM2VhZjZiYWM0MDQzMjlhZTczOWUxNDk1MjJjYmMyLmJpbmRQb3B1cChwb3B1cF9hYjlhNjU4ZjRhOTA0NjkxYTU2MDFmNzk2ZGQ1MDM3ZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfODIzZWFmNmJhYzQwNDMyOWFlNzM5ZTE0OTUyMmNiYzIuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNzQ1N2EwYTY3OTI4NGQwNWI4YmIzZjliZjdiOTM4MGIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjcyNSwgODAuMzkzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWUxYzkwYzU4ODc2NDc2OWE1ZjNjNjE3OTk1ZDJlMTYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGNkNzcyYzljOTNiNGNiNzhhMjk4MjMzNDVhZGE0NzUgPSAkKGA8ZGl2IGlkPSJodG1sXzBjZDc3MmM5YzkzYjRjYjc4YTI5ODIzMzQ1YWRhNDc1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDguNDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYWUxYzkwYzU4ODc2NDc2OWE1ZjNjNjE3OTk1ZDJlMTYuc2V0Q29udGVudChodG1sXzBjZDc3MmM5YzkzYjRjYjc4YTI5ODIzMzQ1YWRhNDc1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNzQ1N2EwYTY3OTI4NGQwNWI4YmIzZjliZjdiOTM4MGIuYmluZFBvcHVwKHBvcHVwX2FlMWM5MGM1ODg3NjQ3NjlhNWYzYzYxNzk5NWQyZTE2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl83NDU3YTBhNjc5Mjg0ZDA1YjhiYjNmOWJmN2I5MzgwYi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zOTAwYjEwNGM3NDc0NzRiYWMxMTcwMmM4ZTQ0OThjNyA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzI1LCA4MC4zOTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84NTA4OTMyZTgxMzY0ZmNjOGQwYTUxYmJkMTRkYTQwYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iZmQ5MTA4MGFlYjY0OTBkODE3MDU3ZGVkYTIzZGFlYSA9ICQoYDxkaXYgaWQ9Imh0bWxfYmZkOTEwODBhZWI2NDkwZDgxNzA1N2RlZGEyM2RhZWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IFZpamF5LCAgIFlpZWxkIDQ5LjA0PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84NTA4OTMyZTgxMzY0ZmNjOGQwYTUxYmJkMTRkYTQwYi5zZXRDb250ZW50KGh0bWxfYmZkOTEwODBhZWI2NDkwZDgxNzA1N2RlZGEyM2RhZWEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zOTAwYjEwNGM3NDc0NzRiYWMxMTcwMmM4ZTQ0OThjNy5iaW5kUG9wdXAocG9wdXBfODUwODkzMmU4MTM2NGZjYzhkMGE1MWJiZDE0ZGE0MGIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzM5MDBiMTA0Yzc0NzQ3NGJhYzExNzAyYzhlNDQ5OGM3LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2Q2MjE0N2IxZTYxNDRmYzI4M2RjMGM2ZGQwNTkzYjljID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43MjUsIDgwLjM5Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzg3OWExNTEzZDVkNTQ1MGNiN2E1MGM1ZDY1OThjMjY2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRjZjA1ZThlOWZlZjQ0YmY5NzE3MWY3NjFhY2E1ZDI2ID0gJChgPGRpdiBpZD0iaHRtbF80Y2YwNWU4ZTlmZWY0NGJmOTcxNzFmNzYxYWNhNWQyNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgNDguODI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzg3OWExNTEzZDVkNTQ1MGNiN2E1MGM1ZDY1OThjMjY2LnNldENvbnRlbnQoaHRtbF80Y2YwNWU4ZTlmZWY0NGJmOTcxNzFmNzYxYWNhNWQyNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2Q2MjE0N2IxZTYxNDRmYzI4M2RjMGM2ZGQwNTkzYjljLmJpbmRQb3B1cChwb3B1cF84NzlhMTUxM2Q1ZDU0NTBjYjdhNTBjNWQ2NTk4YzI2NikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZDYyMTQ3YjFlNjE0NGZjMjgzZGMwYzZkZDA1OTNiOWMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNWU2MDhjODNlM2U2NDE4Yzk2MjExNTI2Nzk1ZmQ5Y2YgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljc2NSwgODAuMzc1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNjc0MjRkMzcyNmI5NGVmZmIxODlhZmQ4ZDZmMGE5YmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYmVmNDFhOWViZjBiNGJkNDlmN2ZlOWUwOGJkZjQ4ZGUgPSAkKGA8ZGl2IGlkPSJodG1sX2JlZjQxYTllYmYwYjRiZDQ5ZjdmZTllMDhiZGY0OGRlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBCYW5nYW5nYSwgICBZaWVsZCA1OC42MTwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjc0MjRkMzcyNmI5NGVmZmIxODlhZmQ4ZDZmMGE5YmMuc2V0Q29udGVudChodG1sX2JlZjQxYTllYmYwYjRiZDQ5ZjdmZTllMDhiZGY0OGRlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNWU2MDhjODNlM2U2NDE4Yzk2MjExNTI2Nzk1ZmQ5Y2YuYmluZFBvcHVwKHBvcHVwXzY3NDI0ZDM3MjZiOTRlZmZiMTg5YWZkOGQ2ZjBhOWJjKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl81ZTYwOGM4M2UzZTY0MThjOTYyMTE1MjY3OTVmZDljZi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zNjk2N2EzY2RkYTQ0NzNjYjQxNWE2NjY5OWVmY2ZiZiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNzY1LCA4MC4zNzVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yZmM3ZmIxODg1ODI0ZDk2ODY3MjE5N2I0OGYyNjIwMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zMTI0MGY0OTkzZGM0NjRhODdiNWY0NDhkYmNmYTNmZCA9ICQoYDxkaXYgaWQ9Imh0bWxfMzEyNDBmNDk5M2RjNDY0YTg3YjVmNDQ4ZGJjZmEzZmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDUyLjA3PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yZmM3ZmIxODg1ODI0ZDk2ODY3MjE5N2I0OGYyNjIwMS5zZXRDb250ZW50KGh0bWxfMzEyNDBmNDk5M2RjNDY0YTg3YjVmNDQ4ZGJjZmEzZmQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zNjk2N2EzY2RkYTQ0NzNjYjQxNWE2NjY5OWVmY2ZiZi5iaW5kUG9wdXAocG9wdXBfMmZjN2ZiMTg4NTgyNGQ5Njg2NzIxOTdiNDhmMjYyMDEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzM2OTY3YTNjZGRhNDQ3M2NiNDE1YTY2Njk5ZWZjZmJmLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzBiNTNjZjUzNmJiYjQ2YWRiYzlhNGNkYzZkMDY2M2Y4ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43NjUsIDgwLjM3NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VhOTUxZWFmMWZjNTRlODc4OTk2MzIxNGRlYmNkM2MyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzVlMDg0YmE4OGU2NzRjYTM5YTQxOTkwMmY3ZmE4ZjJkID0gJChgPGRpdiBpZD0iaHRtbF81ZTA4NGJhODhlNjc0Y2EzOWE0MTk5MDJmN2ZhOGYyZCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNTEuOTI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2VhOTUxZWFmMWZjNTRlODc4OTk2MzIxNGRlYmNkM2MyLnNldENvbnRlbnQoaHRtbF81ZTA4NGJhODhlNjc0Y2EzOWE0MTk5MDJmN2ZhOGYyZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzBiNTNjZjUzNmJiYjQ2YWRiYzlhNGNkYzZkMDY2M2Y4LmJpbmRQb3B1cChwb3B1cF9lYTk1MWVhZjFmYzU0ZTg3ODk5NjMyMTRkZWJjZDNjMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMGI1M2NmNTM2YmJiNDZhZGJjOWE0Y2RjNmQwNjYzZjguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZmM3MzY0NzNjMDcxNDY4NTk0ODNjYjJkMTI2YTBmYTQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljc2MiwgODAuMzg0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2M3ZDdmMGMzMjIzNGM2NWFiNzQ2MWVkNzYwYzEyODIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2Y0YmY5NzI4YjFkNDIwOTliM2QyY2QyYjcyZjI4YWMgPSAkKGA8ZGl2IGlkPSJodG1sXzNmNGJmOTcyOGIxZDQyMDk5YjNkMmNkMmI3MmYyOGFjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBWaWpheSwgICBZaWVsZCA1MS41PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jYzdkN2YwYzMyMjM0YzY1YWI3NDYxZWQ3NjBjMTI4Mi5zZXRDb250ZW50KGh0bWxfM2Y0YmY5NzI4YjFkNDIwOTliM2QyY2QyYjcyZjI4YWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9mYzczNjQ3M2MwNzE0Njg1OTQ4M2NiMmQxMjZhMGZhNC5iaW5kUG9wdXAocG9wdXBfY2M3ZDdmMGMzMjIzNGM2NWFiNzQ2MWVkNzYwYzEyODIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyX2ZjNzM2NDczYzA3MTQ2ODU5NDgzY2IyZDEyNmEwZmE0LmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzQ1OTc3OThhZmZiMDRhNzJhMTcwYjUxMzI3MTE4MjljID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC43NjIsIDgwLjM4NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzVlYWNkNzhjMzdkNDQ4YjdiY2ZmNzExMGIzZDc5OTE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNhOWVkMjk5ZjI3ODQxZmU5NmU3YmRiYzU0ZTE0NmI4ID0gJChgPGRpdiBpZD0iaHRtbF8zYTllZDI5OWYyNzg0MWZlOTZlN2JkYmM1NGUxNDZiOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogVmlqYXksICAgWWllbGQgMzguOTI8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzVlYWNkNzhjMzdkNDQ4YjdiY2ZmNzExMGIzZDc5OTE0LnNldENvbnRlbnQoaHRtbF8zYTllZDI5OWYyNzg0MWZlOTZlN2JkYmM1NGUxNDZiOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzQ1OTc3OThhZmZiMDRhNzJhMTcwYjUxMzI3MTE4MjljLmJpbmRQb3B1cChwb3B1cF81ZWFjZDc4YzM3ZDQ0OGI3YmNmZjcxMTBiM2Q3OTkxNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfNDU5Nzc5OGFmZmIwNGE3MmExNzBiNTEzMjcxMTgyOWMuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOTJlYjU2YjljOWQ4NDk1MTgyY2E1YWZlNDkyYTQxMTggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4Ljc2MSwgODAuMzg0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjgxODFiN2I2MmU2NDg4Njg0Yjg5N2QzOTk0YTdkMDYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDA3NGM1ZjQyYzlhNGMxNWIxYmI2MzMyM2RhNzUzZDYgPSAkKGA8ZGl2IGlkPSJodG1sX2QwNzRjNWY0MmM5YTRjMTViMWJiNjMzMjNkYTc1M2Q2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDQuNTc8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I4MTgxYjdiNjJlNjQ4ODY4NGI4OTdkMzk5NGE3ZDA2LnNldENvbnRlbnQoaHRtbF9kMDc0YzVmNDJjOWE0YzE1YjFiYjYzMzIzZGE3NTNkNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzkyZWI1NmI5YzlkODQ5NTE4MmNhNWFmZTQ5MmE0MTE4LmJpbmRQb3B1cChwb3B1cF9iODE4MWI3YjYyZTY0ODg2ODRiODk3ZDM5OTRhN2QwNikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfOTJlYjU2YjljOWQ4NDk1MTgyY2E1YWZlNDkyYTQxMTguYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTE0ZTRlMDY3NTUwNDY4Yzg1ZWMyMjk5NDkwN2I2NjcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYwOCwgODAuNzk5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTdhNDY0NjQzNmJkNDMwMDllNWI2MTYwM2E4YWUxYjggPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWU1MzBhN2Y1YzU1NGIxYWI4MmQxZGNiM2I3ZDA2NTggPSAkKGA8ZGl2IGlkPSJodG1sX2VlNTMwYTdmNWM1NTRiMWFiODJkMWRjYjNiN2QwNjU4IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBOTCA5NzEsICAgWWllbGQgNDYuNTk8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzU3YTQ2NDY0MzZiZDQzMDA5ZTViNjE2MDNhOGFlMWI4LnNldENvbnRlbnQoaHRtbF9lZTUzMGE3ZjVjNTU0YjFhYjgyZDFkY2IzYjdkMDY1OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzExNGU0ZTA2NzU1MDQ2OGM4NWVjMjI5OTQ5MDdiNjY3LmJpbmRQb3B1cChwb3B1cF81N2E0NjQ2NDM2YmQ0MzAwOWU1YjYxNjAzYThhZTFiOCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfMTE0ZTRlMDY3NTUwNDY4Yzg1ZWMyMjk5NDkwN2I2NjcuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfN2E0NDE0NDM2MjU5NGRkYmIxZTE4ODYxMzFkZmVhZDIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjYwOCwgODAuNzk5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmI0YTU3NWM1ZTY3NDIzMGIxZjdmNDFhOTAzZjkwM2QgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjIyZDRlZGMzNjFkNGM3ZDgyNDg3NzQ0MTU3NTIzZmUgPSAkKGA8ZGl2IGlkPSJodG1sX2YyMmQ0ZWRjMzYxZDRjN2Q4MjQ4Nzc0NDE1NzUyM2ZlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1MC4xNjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmI0YTU3NWM1ZTY3NDIzMGIxZjdmNDFhOTAzZjkwM2Quc2V0Q29udGVudChodG1sX2YyMmQ0ZWRjMzYxZDRjN2Q4MjQ4Nzc0NDE1NzUyM2ZlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfN2E0NDE0NDM2MjU5NGRkYmIxZTE4ODYxMzFkZmVhZDIuYmluZFBvcHVwKHBvcHVwXzJiNGE1NzVjNWU2NzQyMzBiMWY3ZjQxYTkwM2Y5MDNkKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl83YTQ0MTQ0MzYyNTk0ZGRiYjFlMTg4NjEzMWRmZWFkMi5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl82Nzk0YzhhMjU2YTA0MTMxODRhYzU1MjY4YzYyMGRhZiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjA3LCA4MC43OTldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80MmY2YmUwOTU2ODQ0N2YwOTlmYzliZTI2OTgxNDUyZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yOGNhN2JmYWVjZDc0MzAyYmViMDhjZDM0MmY4MTZkNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMjhjYTdiZmFlY2Q3NDMwMmJlYjA4Y2QzNDJmODE2ZDUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IExvY2FsLCAgIFlpZWxkIDQ3LjkyPC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80MmY2YmUwOTU2ODQ0N2YwOTlmYzliZTI2OTgxNDUyZS5zZXRDb250ZW50KGh0bWxfMjhjYTdiZmFlY2Q3NDMwMmJlYjA4Y2QzNDJmODE2ZDUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82Nzk0YzhhMjU2YTA0MTMxODRhYzU1MjY4YzYyMGRhZi5iaW5kUG9wdXAocG9wdXBfNDJmNmJlMDk1Njg0NDdmMDk5ZmM5YmUyNjk4MTQ1MmUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgbWFya2VyXzY3OTRjOGEyNTZhMDQxMzE4NGFjNTUyNjhjNjIwZGFmLmJpbmRUb29sdGlwKAogICAgICAgICAgICBgPGRpdj5gCiAgICAgICAgICAgICsgYENsaWNrIG1lIWAgKyBgPC9kaXY+YCwKICAgICAgICAgICAgeyJzdGlja3kiOiB0cnVlfQogICAgICAgICk7CiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2YwM2NmNzVlODBhYzQ0YjFhNjJiNDEzZTZmZWEzODNiID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyOC42OTIsIDgwLjQ0M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81ZDM0YjIzM2I4ZDk0MmY2YTA1NjkxOGQxNzI3NDAyYyk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2JhYzk4YjU3ZjVhNzQ5ODE5YWU5MDY5Y2UzOTc2MTg3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE4ODIzMGIwODc0YjQ1NTBiNmI0YTBkZjA1ZDIxMzQxID0gJChgPGRpdiBpZD0iaHRtbF8xODgyMzBiMDg3NGI0NTUwYjZiNGEwZGYwNWQyMTM0MSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+V2hlYXQgdmFyaWV0eTogTG9jYWwsICAgWWllbGQgNDkuNjE8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JhYzk4YjU3ZjVhNzQ5ODE5YWU5MDY5Y2UzOTc2MTg3LnNldENvbnRlbnQoaHRtbF8xODgyMzBiMDg3NGI0NTUwYjZiNGEwZGYwNWQyMTM0MSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2YwM2NmNzVlODBhYzQ0YjFhNjJiNDEzZTZmZWEzODNiLmJpbmRQb3B1cChwb3B1cF9iYWM5OGI1N2Y1YTc0OTgxOWFlOTA2OWNlMzk3NjE4NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICBtYXJrZXJfZjAzY2Y3NWU4MGFjNDRiMWE2MmI0MTNlNmZlYTM4M2IuYmluZFRvb2x0aXAoCiAgICAgICAgICAgIGA8ZGl2PmAKICAgICAgICAgICAgKyBgQ2xpY2sgbWUhYCArIGA8L2Rpdj5gLAogICAgICAgICAgICB7InN0aWNreSI6IHRydWV9CiAgICAgICAgKTsKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfN2Q5YWE3N2Y5Y2RmNGMxMTkzMTYwYzBkZDVmODY1ODAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjY5MiwgODAuNDQ0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzVkMzRiMjMzYjhkOTQyZjZhMDU2OTE4ZDE3Mjc0MDJjKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2JiYjY3YmQyODczNDY5ZGIzZWFmMTIwYTk3M2IyZTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGRjMDczYWQ5ZThmNDNiMmJhMGRkM2I0ZDllMTVhZjYgPSAkKGA8ZGl2IGlkPSJodG1sXzBkYzA3M2FkOWU4ZjQzYjJiYTBkZDNiNGQ5ZTE1YWY2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5XaGVhdCB2YXJpZXR5OiBMb2NhbCwgICBZaWVsZCA1NC45MjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2JiYjY3YmQyODczNDY5ZGIzZWFmMTIwYTk3M2IyZTAuc2V0Q29udGVudChodG1sXzBkYzA3M2FkOWU4ZjQzYjJiYTBkZDNiNGQ5ZTE1YWY2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfN2Q5YWE3N2Y5Y2RmNGMxMTkzMTYwYzBkZDVmODY1ODAuYmluZFBvcHVwKHBvcHVwX2NiYmI2N2JkMjg3MzQ2OWRiM2VhZjEyMGE5NzNiMmUwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl83ZDlhYTc3ZjljZGY0YzExOTMxNjBjMGRkNWY4NjU4MC5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84Njc2MTNjN2IxYzM0MmI1YmJjMzFiODZiYTdhZDBkZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMjguNjkyLCA4MC40NDRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNWQzNGIyMzNiOGQ5NDJmNmEwNTY5MThkMTcyNzQwMmMpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iYzVhN2JiMDNkNDU0ZWU2YmExMDM4NGM1MjhlMDE5NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85ZjdhNWFmZTVjOGY0OWZmYjE5ZmQwMjVhN2VkODUyMyA9ICQoYDxkaXYgaWQ9Imh0bWxfOWY3YTVhZmU1YzhmNDlmZmIxOWZkMDI1YTdlZDg1MjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPldoZWF0IHZhcmlldHk6IE5MIDk3MSwgICBZaWVsZCA0NS44NDwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYmM1YTdiYjAzZDQ1NGVlNmJhMTAzODRjNTI4ZTAxOTUuc2V0Q29udGVudChodG1sXzlmN2E1YWZlNWM4ZjQ5ZmZiMTlmZDAyNWE3ZWQ4NTIzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODY3NjEzYzdiMWMzNDJiNWJiYzMxYjg2YmE3YWQwZGUuYmluZFBvcHVwKHBvcHVwX2JjNWE3YmIwM2Q0NTRlZTZiYTEwMzg0YzUyOGUwMTk1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIG1hcmtlcl84Njc2MTNjN2IxYzM0MmI1YmJjMzFiODZiYTdhZDBkZS5iaW5kVG9vbHRpcCgKICAgICAgICAgICAgYDxkaXY+YAogICAgICAgICAgICArIGBDbGljayBtZSFgICsgYDwvZGl2PmAsCiAgICAgICAgICAgIHsic3RpY2t5IjogdHJ1ZX0KICAgICAgICApOwogICAgICAgIAo8L3NjcmlwdD4= onload="this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>

Sentinel-2 and Worldclim data extraction from Google Earth Engine

# Athenticate to your GEE account. 
!earthengine authenticate
# Earth Engine Python API
ee.Initialize()

Sentinel-2 imagery bands and indices composition

The purpose of this excersice is we want to have bands and indices information that may be helpful to modeling wheat yiled from temporal and spatial perspective

# From GEE
# If you are interested in using Landsat8 surface reflectance, see data over here https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1_SR#bands
# The following steps showing how to extrac Sentinel-2 from GEE
aoi = ee.Geometry.Rectangle(terai_bbox.tolist())
band_sel = ('B2', 'B3', 'B4', 'B8', 'B11', 'B12')

sentinel_scenes = ee.ImageCollection("COPERNICUS/S2")\
    .filterBounds(aoi)\
    .filterDate('2018-01-01', '2018-12-31')\
    .select(band_sel)\
    .filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE',10))

scenes = sentinel_scenes.getInfo()
[print(scene['id']) for scene in scenes["features"]]

sentinel_mosaic = sentinel_scenes.mean().rename(band_sel)

sentinel_mosaic.getInfo()

This next cell will export a Geotiff for each point of interest, by creating a bounding box around each point and then clipping the Sentinel layer to that area.

# crop_data = op.join(my_root_dir, "mosaic_s2")
"Colab notebooks/data/mosaic_s2"

Quiz

Let's extract seasonal Sentinel-2 instead of annual data

Run the Export (Optional)

 # This task will run in the background even if you close this notebook.
  # You can also check on the status of the task through the Javascript GEE interface
  # https://code.earthengine.google.com
  task.start()
# If you want to keep track of the export you can run this code
# However if run this, you will need to wait for it to finish before running additional code

while task.active():
  print('Polling for task (id: {}).'.format(task.id))
  time.sleep(15)

Visualizing Sentinel-2 imagery RGB in 2018 in our study area

# To make a map we first need some helper functions

# Define the URL format used for Earth Engine generated map tiles.
EE_TILES = 'https://earthengine.googleapis.com/map/{mapid}/{{z}}/{{x}}/{{y}}?token={token}'

#@title Mapdisplay: Display GEE objects using folium.
def Mapdisplay(center, dicc, Tiles="OpensTreetMap",zoom_start=8):
    '''
    :param center: Center of the map (Latitude and Longitude).
    :param dicc: Earth Engine Geometries or Tiles dictionary
    :param Tiles: Mapbox Bright,Mapbox Control Room,Stamen Terrain,Stamen Toner,stamenwatercolor,cartodbpositron.
    :zoom_start: Initial zoom level for the map.
    :return: A folium.Map object.
    '''
    mapViz = folium.Map(location=center,tiles=Tiles, zoom_start=zoom_start)
    for k,v in dicc.items():
      if gpd.geodataframe.GeoDataFrame == type(v):
        folium.GeoJson(
        data = v,
        name = k
          ).add_to(mapViz) 
      elif ee.image.Image in [type(x) for x in v.values()]:
        folium.TileLayer(
            tiles = v["tile_fetcher"].url_format,
            attr  = 'Google Earth Engine',
            overlay =True,
            name  = k
          ).add_to(mapViz)
      else:
        folium.GeoJson(
        data = v,
        name = k
          ).add_to(mapViz)
    mapViz.add_child(folium.LayerControl())
    return mapViz
s2_vis_params = {
  'bands': ['B4', 'B3', 'B2'],
  'min': 0,
  'max': 3000,
}

Mapdisplay(center=[y_map, x_map],
           dicc={'S2':sentinel_mosaic.getMapId(s2_vis_params)},
                #  'TrainingData':wheat_2018_disctrict}, 
           zoom_start=11)
Make this Notebook Trusted to load map: File -> Trust Notebook<iframe src="about:blank" style="position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;" data-html=PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4xMi40Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdjZG4uZ2l0aGFjay5jb20vcHl0aG9uLXZpc3VhbGl6YXRpb24vZm9saXVtL21hc3Rlci9mb2xpdW0vdGVtcGxhdGVzL2xlYWZsZXQuYXdlc29tZS5yb3RhdGUuY3NzIi8+CiAgICA8c3R5bGU+aHRtbCwgYm9keSB7d2lkdGg6IDEwMCU7aGVpZ2h0OiAxMDAlO21hcmdpbjogMDtwYWRkaW5nOiAwO308L3N0eWxlPgogICAgPHN0eWxlPiNtYXAge3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2JvdHRvbTowO3JpZ2h0OjA7bGVmdDowO308L3N0eWxlPgogICAgCiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLAogICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgIDxzdHlsZT4jbWFwX2Y0YWQ0MTZmZWY4YjQxY2Y4MzdhOWNiN2M4NDQ5OTIyIHsKICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgICAgICAgd2lkdGg6IDEwMC4wJTsKICAgICAgICBoZWlnaHQ6IDEwMC4wJTsKICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgIHRvcDogMC4wJTsKICAgICAgICB9CiAgICA8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgPGRpdiBjbGFzcz0iZm9saXVtLW1hcCIgaWQ9Im1hcF9mNGFkNDE2ZmVmOGI0MWNmODM3YTljYjdjODQ0OTkyMiIgPjwvZGl2Pgo8L2JvZHk+CjxzY3JpcHQ+ICAgIAogICAgCiAgICAKICAgICAgICB2YXIgYm91bmRzID0gbnVsbDsKICAgIAoKICAgIHZhciBtYXBfZjRhZDQxNmZlZjhiNDFjZjgzN2E5Y2I3Yzg0NDk5MjIgPSBMLm1hcCgKICAgICAgICAnbWFwX2Y0YWQ0MTZmZWY4YjQxY2Y4MzdhOWNiN2M4NDQ5OTIyJywgewogICAgICAgIGNlbnRlcjogWzI4LjQ5MjUsIDgwLjkwNjVdLAogICAgICAgIHpvb206IDExLAogICAgICAgIG1heEJvdW5kczogYm91bmRzLAogICAgICAgIGxheWVyczogW10sCiAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICB9KTsKCgogICAgCiAgICB2YXIgdGlsZV9sYXllcl85YjE3YzRjNTU3MjU0MTk0OWMyNzQyYTk1NTlkYjUyZCA9IEwudGlsZUxheWVyKAogICAgICAgICdodHRwczovL3tzfS50aWxlLm9wZW5zdHJlZXRtYXAub3JnL3t6fS97eH0ve3l9LnBuZycsCiAgICAgICAgewogICAgICAgICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgICAgICAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICAgICAgICJtYXhOYXRpdmVab29tIjogMTgsCiAgICAgICAgIm1heFpvb20iOiAxOCwKICAgICAgICAibWluWm9vbSI6IDAsCiAgICAgICAgIm5vV3JhcCI6IGZhbHNlLAogICAgICAgICJvcGFjaXR5IjogMSwKICAgICAgICAic3ViZG9tYWlucyI6ICJhYmMiLAogICAgICAgICJ0bXMiOiBmYWxzZQp9KS5hZGRUbyhtYXBfZjRhZDQxNmZlZjhiNDFjZjgzN2E5Y2I3Yzg0NDk5MjIpOwogICAgdmFyIHRpbGVfbGF5ZXJfNTQzYzU3Yzc4ODM3NDQyY2FkOThmZjk2YTYwOTRhZTEgPSBMLnRpbGVMYXllcigKICAgICAgICAnaHR0cHM6Ly9lYXJ0aGVuZ2luZS5nb29nbGVhcGlzLmNvbS92MWFscGhhL3Byb2plY3RzL2VhcnRoZW5naW5lLWxlZ2FjeS9tYXBzLzkyYjU4MzM2NjA5OTdkOTY3OThhN2NlYjU5MjkzNjU1LWViNDkxYWI1Yjc4NTg3YWRjMjQyMzg5ZmFhYTNiYmQyL3RpbGVzL3t6fS97eH0ve3l9JywKICAgICAgICB7CiAgICAgICAgImF0dHJpYnV0aW9uIjogIkdvb2dsZSBFYXJ0aCBFbmdpbmUiLAogICAgICAgICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAgICAgICAibWF4TmF0aXZlWm9vbSI6IDE4LAogICAgICAgICJtYXhab29tIjogMTgsCiAgICAgICAgIm1pblpvb20iOiAwLAogICAgICAgICJub1dyYXAiOiBmYWxzZSwKICAgICAgICAib3BhY2l0eSI6IDEsCiAgICAgICAgInN1YmRvbWFpbnMiOiAiYWJjIiwKICAgICAgICAidG1zIjogZmFsc2UKfSkuYWRkVG8obWFwX2Y0YWQ0MTZmZWY4YjQxY2Y4MzdhOWNiN2M4NDQ5OTIyKTsKICAgIAogICAgICAgICAgICB2YXIgbGF5ZXJfY29udHJvbF83NDk0ZmU5MTljYjI0OTJkYjQwMDU1ZDk5M2JkM2QwYyA9IHsKICAgICAgICAgICAgICAgIGJhc2VfbGF5ZXJzIDogeyAib3BlbnN0cmVldG1hcCIgOiB0aWxlX2xheWVyXzliMTdjNGM1NTcyNTQxOTQ5YzI3NDJhOTU1OWRiNTJkLCB9LAogICAgICAgICAgICAgICAgb3ZlcmxheXMgOiB7ICJTMiIgOiB0aWxlX2xheWVyXzU0M2M1N2M3ODgzNzQ0MmNhZDk4ZmY5NmE2MDk0YWUxLCB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICBMLmNvbnRyb2wubGF5ZXJzKAogICAgICAgICAgICAgICAgbGF5ZXJfY29udHJvbF83NDk0ZmU5MTljYjI0OTJkYjQwMDU1ZDk5M2JkM2QwYy5iYXNlX2xheWVycywKICAgICAgICAgICAgICAgIGxheWVyX2NvbnRyb2xfNzQ5NGZlOTE5Y2IyNDkyZGI0MDA1NWQ5OTNiZDNkMGMub3ZlcmxheXMsCiAgICAgICAgICAgICAgICB7cG9zaXRpb246ICd0b3ByaWdodCcsCiAgICAgICAgICAgICAgICAgY29sbGFwc2VkOiB0cnVlLAogICAgICAgICAgICAgICAgIGF1dG9aSW5kZXg6IHRydWUKICAgICAgICAgICAgICAgIH0pLmFkZFRvKG1hcF9mNGFkNDE2ZmVmOGI0MWNmODM3YTljYjdjODQ0OTkyMik7CiAgICAgICAgICAgIAogICAgICAgIAo8L3NjcmlwdD4= onload="this.contentDocument.open();this.contentDocument.write(atob(this.getAttribute('data-html')));this.contentDocument.close();" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe>

Extract average temperature and precipitation from WorldClim

To enrich the attributes data for crop yield modeling, you can go to WorldClim to explore data including:

  • Minimum temperature
  • Maximum temperature
  • Average temperature
  • Precipitation
  • Solar radiation
  • Wind speed
  • Water vapor presure

But only average temperature and precipitation are available in GEE. More information of the dataset on GEE, please look over here.

# worldclim data on GEE
# https://developers.google.com/earth-engine/datasets/catalog/WORLDCLIM_V1_MONTHLY#bands
wcband_sel = ['tavg', 'prec']
worldclim = ee.ImageCollection("WORLDCLIM/V1/MONTHLY").select(wcband_sel)
worldclim_mosaic = worldclim.mean().rename(wcband_sel) 
wheat_2018.head()
Lat Long District wheat_variety Treat wheat_yield PH OM geometry
0 28.980 80.193 Kanchanpur Banganga D1 53.92 7.817228 1.688501 POINT (80.19300 28.98000)
1 28.980 80.193 Kanchanpur Tilganga D2 50.62 7.817228 1.688501 POINT (80.19300 28.98000)
2 28.980 80.193 Kanchanpur NHS 1755 D3 40.44 7.817228 1.688501 POINT (80.19300 28.98000)
3 28.986 80.188 Kanchanpur NL 971 D1 46.32 7.725938 1.644356 POINT (80.18800 28.98600)
4 28.986 80.188 Kanchanpur Vijay D2 62.50 7.725938 1.644356 POINT (80.18800 28.98600)

Quiz

Let's extract other dataset under WorldClim, e.g. max temperature, min temperature

Combine Sentinel-2 and Worldclim data

# Helper functions
def normalized_arr(ls_data):
  """normalized data 
  Args:
      np_array: data in a list
  Returns:
      x_scaled: rescaled/nomalized data in the value range between 0 and 1
  """
  arr = np.array(ls_data)
  #normalized the data 
  min_max_scaler = preprocessing.MinMaxScaler()
  x_scaled = min_max_scaler.fit_transform(arr)
  return x_scaled

def construct_indices(band1, band2):
  """compute band indices
  Args:
      band1, band2: specific band data 
  Returns:
      ind: index, e.g. ndvi
  """
  ind = (band1 - band2)/(band1 + band2)
  return ind

Sentinel-2 data reconstruction

wheat_2018_pts.head()
Lat Long District wheat_variety Treat wheat_yield PH OM geometry
0 28.980 80.193 Kanchanpur Banganga D1 53.92 7.817228 1.688501 POINT (80.19300 28.98000)
1 28.980 80.193 Kanchanpur Tilganga D2 50.62 7.817228 1.688501 POINT (80.19300 28.98000)
2 28.980 80.193 Kanchanpur NHS 1755 D3 40.44 7.817228 1.688501 POINT (80.19300 28.98000)
3 28.986 80.188 Kanchanpur NL 971 D1 46.32 7.725938 1.644356 POINT (80.18800 28.98600)
4 28.986 80.188 Kanchanpur Vijay D2 62.50 7.725938 1.644356 POINT (80.18800 28.98600)
wheat_2018_gdf = wheat_2018_pts.geometry.buffer(0.05)
wheat_2018_gdf['geometry_x'] = wheat_2018_pts.geometry.buffer(0.05)
wheat_2018_gdf.head()
0    POLYGON ((80.24300 28.98000, 80.24276 28.97510...
1    POLYGON ((80.24300 28.98000, 80.24276 28.97510...
2    POLYGON ((80.24300 28.98000, 80.24276 28.97510...
3    POLYGON ((80.23800 28.98600, 80.23776 28.98110...
4    POLYGON ((80.23800 28.98600, 80.23776 28.98110...
dtype: geometry
# Reference the raster on disk.
bands = []
for i in range(len(wheat_2018)):
  raster = op.join(crop_data,'mosaic_s2',f'S2_mosaic_Terai_Nepal_2018_{i}.tif')
  with rasterio.open(raster, 'r') as src:
    frsc = src.read()
    print(frsc.mean(axis=(1, 2)))
    bands.append(frsc.mean(axis=(1, 2)))
band_arr = normalized_arr(bands)
bands_df = pd.DataFrame(band_arr, columns=['B2', 'B3', 'B4', 'B8', 'B11', 'B12'])
bands_df['ndvi'] = construct_indices(bands_df.B8, bands_df.B4)
bands_df['ndwi'] = construct_indices(bands_df.B8, bands_df.B3)
bands_df.head()
B2 B3 B4 B8 B11 B12 ndvi ndwi
0 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595
1 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595
2 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595
3 0.223089 0.326231 0.384491 0.558959 0.269641 0.335698 0.184925 0.262913
4 0.223089 0.326231 0.384491 0.558959 0.269641 0.335698 0.184925 0.262913
len(bands_df)
145

Adding Worldclim data

wcs = []
for i in range(len(wheat_2018)):
  raster = op.join(crop_data,'worldclim',f'wc_monthly_{i}.tif')
  with rasterio.open(raster, 'r') as src:
    frsc = src.read()
    print(frsc.mean(axis=(1, 2)))
    wcs.append(frsc.mean(axis=(1, 2)))
wc_arr = normalized_arr(wcs)
wcs_df = pd.DataFrame(wc_arr, columns=['tavg', 'prec'])
wcs_df.head()
tavg prec
0 0.598473 0.372607
1 0.598473 0.372607
2 0.598473 0.372607
3 0.538391 0.391679
4 0.538391 0.391679
len(wcs_df)
145

Concatenate Sentinel-2 and Worldclim to the wheat yield dataframe

dfs = [wheat_2018, bands_df, wcs_df, soil_df, indices_df]
wheat_2010_all = pd.concat(dfs, axis=1)
wheat_2010_all.head()
Lat Long District wheat_variety Treat wheat_yield PH OM geometry B2 B3 B4 B8 B11 B12 ndvi ndwi tavg prec
0 28.980 80.193 Kanchanpur Banganga D1 53.92 7.817228 1.688501 POINT (80.19300 28.98000) 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595 0.598473 0.372607
1 28.980 80.193 Kanchanpur Tilganga D2 50.62 7.817228 1.688501 POINT (80.19300 28.98000) 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595 0.598473 0.372607
2 28.980 80.193 Kanchanpur NHS 1755 D3 40.44 7.817228 1.688501 POINT (80.19300 28.98000) 0.246886 0.340987 0.397884 0.441628 0.281341 0.334612 0.052106 0.128595 0.598473 0.372607
3 28.986 80.188 Kanchanpur NL 971 D1 46.32 7.725938 1.644356 POINT (80.18800 28.98600) 0.223089 0.326231 0.384491 0.558959 0.269641 0.335698 0.184925 0.262913 0.538391 0.391679
4 28.986 80.188 Kanchanpur Vijay D2 62.50 7.725938 1.644356 POINT (80.18800 28.98600) 0.223089 0.326231 0.384491 0.558959 0.269641 0.335698 0.184925 0.262913 0.538391 0.391679
wheat_2010_all
len(wheat_2010_all)
145

Quiz

If you want to include both 'wheat_variety' and 'Treat' in the regressor, what should you do next?

# write you update code here

Crop yield modeling with XGBoost

Beginer friendly XGBoost regressor tutorial

More parameter search and tunning tutorial

Best ways to evaluate regression model: 3 Best metrics to evaluate Regression Model?

Train Model Using k-fold Cross Validation

X = wheat_2010_all[['PH', 'OM', 'B2', 'B3', 'B4', 'B8', 'B11', 'B12', 'ndvi', 'ndwi', 'tavg', 'prec']]
y= wheat_2010_all.wheat_yield

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)

Configure the Model

# learn more about the regressor parameter https://xgboost.readthedocs.io/en/latest/parameter.html#learning-task-parameters
xg_reg= xgb.XGBRegressor(objective = 'reg:squarederror' , 
                         colsample_bytree=0.4,
                         gamma=0,                 
                         learning_rate=0.07,
                         max_depth=3,
                         min_child_weight=1.5,
                         n_estimators=10000,                                                                    
                         reg_alpha=0.75,
                         reg_lambda=0.45,
                         subsample=0.6,
                         seed=42)

Fit the Model then Predict

xg_reg.fit(X_train,y_train)

preds = xg_reg.predict(X_test)

Evaluate the Model

rmse = np.sqrt(mean_squared_error(y_test, preds))
print("RMSE: %f" % (rmse))
RMSE: 7.058864

Visualize Metrics

Now we can plot y_test (test data) vs preds (predictions). Then we can investigage the variable importance to the model.

plt.scatter(preds, y_test, c = "green", marker = "s")
plt.title("Scatter plot for y_test and prediction")
plt.xlabel("Prediction")
plt.ylabel("True labels")
plt.show()
xgb.plot_importance(xg_reg)
plt.rcParams['figure.figsize'] = [10, 20]
plt.show()

Quiz

Try to use grid search and parameter search and tunning to tune the model

# write your code here

# provide script here
# this will take a bit of time to run, like 30mins
parameters_for_testing = {
 'colsample_bytree':[0.4,0.6,0.8],
 'gamma':[0,0.03,0.1,0.3],
 'min_child_weight':[1.5,6,10],
 'learning_rate':[0.1,0.07],
 'max_depth':[3,5],
 'n_estimators':[5000, 10000, 15000, 20000],
 'reg_alpha':[1e-5, 1e-2, 0.75],
 'reg_lambda':[1e-5, 1e-2, 0.45],
 'subsample':[0.6,0.95] 
}
 
xgb_model = xgb.XGBRegressor(learning_rate =0.1, n_estimators=1000, max_depth=5, min_child_weight=1, gamma=0, subsample=0.8, colsample_bytree=0.8, nthread=6, scale_pos_weight=1, seed=27)
gsearch1 = GridSearchCV(estimator = xgb_model, param_grid = parameters_for_testing, n_jobs=4,iid=False, verbose=10,scoring='neg_mean_squared_error')
gsearch1.fit(X_train,y_train)
print (gsearch1.grid_scores_)
print('best params')
print (gsearch1.best_params_)
print('best score')
print (gsearch1.best_score_)