You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
956 lines
159 KiB
Plaintext
956 lines
159 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Pyrocko Notebook\n",
|
|
"## Double Couple Waveform Inversion (The 2009 Aquila Earthquake)\n",
|
|
"\n",
|
|
"In this Jupyter-notebook we look at teleseismic waveforms of the 2009 Aquila Earthquake and setup `pyrocko.gf` forward modelling to invert for the double couple mechanism of the event. We will use `pyrocko` to handle the seismic data and execute the forward modelling based on pre-calculated Green's function stores, `scipy` delivers the optimisation algorithms.\n",
|
|
"Besides this Notebook you will also need to download the utils_nb.py file from this repository.\n",
|
|
"\n",
|
|
"_Authors:_\n",
|
|
"Andreas Steinberg, Marius Isken\n",
|
|
"\n",
|
|
"-Nov. 2017"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"%matplotlib inline\n",
|
|
"import time\n",
|
|
"import os\n",
|
|
"import scipy\n",
|
|
"import numpy as num\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"import plotly.plotly as py\n",
|
|
"from collections import OrderedDict\n",
|
|
"\n",
|
|
"import utils_nb\n",
|
|
"\n",
|
|
"from pyrocko import gf, trace\n",
|
|
"from pyrocko import moment_tensor as mtm\n",
|
|
"from pyrocko.gf import ws, LocalEngine, Target, DCSource\n",
|
|
"from pyrocko import util, pile, model, config, trace, io, pile, catalog\n",
|
|
"\n",
|
|
"km = 1000."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Optimisation Parameters\n",
|
|
"Setup of the optimisation parameters, as well as boundaries for the source parameters."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"component = 'Z'\n",
|
|
"f_low = 0.05 # Hz, for a lowpass filter\n",
|
|
"taper = trace.CosFader(xfade=2.0) # Cosine taper, 2s fade\n",
|
|
"\n",
|
|
"phase = 'P' # Phase to fit\n",
|
|
"tmin_fit = 15. # [s] to fit before synthetic phase onset (from GFStore)\n",
|
|
"tmax_fit = 35. # [s] ... after\n",
|
|
"\n",
|
|
"bounds = OrderedDict([\n",
|
|
" ('north_shift', (-20.*km, 20.*km)),\n",
|
|
" ('east_shift', (-20.*km, 20.*km)),\n",
|
|
" ('depth', (3.*km, 8.*km)),\n",
|
|
" ('magnitude', (6.2, 6.4)),\n",
|
|
" ('strike', (100., 140.)),\n",
|
|
" ('dip', (40., 60.)),\n",
|
|
" ('rake', (-100, -150.)),\n",
|
|
" ('timeshift', (-20., 20.)),\n",
|
|
" ])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Load the Waveforms\n",
|
|
"We download the instrument-corrected seismic waveforms and use a `pyrocko.pile` to manage the data."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"selecting files... done. 58 files selected.\n",
|
|
"Looking at files [-----------------------------------------] 100% Time: 0:00:00\n",
|
|
"Scanning files [-------------------------------------------] 100% Time: 0:00:00\n",
|
|
"Cannot read file '/home/marius/Development/pyrocko-notebooks/data/aquila_realdata/stations_short.txt': No SEED data detected (file: /home/marius/Development/pyrocko-notebooks/data/aquila_realdata/stations_short.txt)\n",
|
|
"The following file caused problems and will be ignored:\n",
|
|
"/home/marius/Development/pyrocko-notebooks/data/aquila_realdata/stations_short.txt\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Download the instrument-corrected 2009 Aquila Earthquake data\n",
|
|
"data_path = utils_nb.download_dir('aquila_realdata/')\n",
|
|
"data = pile.make_pile([data_path])\n",
|
|
"traces = data.all() # retrieves the raw waveform data as a 2D `numpy.array`.\n",
|
|
"\n",
|
|
"for tr in traces:\n",
|
|
" tr.lowpass(4, f_low)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Initialize Forward Modelling Engine (Seismosizer)\n",
|
|
"We download the precalculated Green's function database (`Store`) *global_2s_25km* from http://kinherd.org"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"store_id = 'global_2s_25km'\n",
|
|
"if not os.path.exists(store_id):\n",
|
|
" ws.download_gf_store(site='kinherd', store_id=store_id)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we fire up the `engine` to forward model synthetic seismograms on our _global_2s_25km_ GF database."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"engine = gf.LocalEngine(store_superdirs=['.']) # The Path to where the gf_store(s)\n",
|
|
"store = engine.get_store(store_id) # Load the store."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Get GlobalCMT Start Model\n",
|
|
"We use the GlobalCMT catalog to search for the 2009 Aquila Earthquake and initalize a source for the starting model."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"tmin = util.str_to_time('2009-04-06 00:00:00') # beginning time of query\n",
|
|
"tmax = util.str_to_time('2009-04-06 05:59:59') # ending time of query\n",
|
|
"event = catalog.GlobalCMT().get_events(\n",
|
|
" time_range=(tmin, tmax),\n",
|
|
" magmin=6.)[0]\n",
|
|
"\n",
|
|
"base_source = gf.MTSource.from_pyrocko_event(event)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Station and _Target_ Setup\n",
|
|
"We use the term _Target_ for a single component of a single station."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"stations_list = model.load_stations('data/aquila_realdata/stations_short.txt')\n",
|
|
"for s in stations_list:\n",
|
|
" s.set_channels_by_name(*component.split())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next we define the `Target` - where to calculate the synthetic seismogram."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"targets=[]\n",
|
|
"for s in stations_list:\n",
|
|
" target = Target(\n",
|
|
" lat=s.lat,\n",
|
|
" lon=s.lon,\n",
|
|
" store_id=store_id, # The gf-store to be used for this target,\n",
|
|
" interpolation='multilinear', # Interpolation method between GFStore nodes\n",
|
|
" quantity='displacement',\n",
|
|
" codes=s.nsl() + ('BH' + component,))\n",
|
|
" targets.append(target)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Objective Function\n",
|
|
"Now the objective function that will be called by `scipy.optimize`:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"source = gf.DCSource(\n",
|
|
" lat=event.lat,\n",
|
|
" lon=event.lon)\n",
|
|
"\n",
|
|
"def update_source(params):\n",
|
|
" s = source\n",
|
|
" s.north_shift = float(params[0])\n",
|
|
" s.east_shift = float(params[1])\n",
|
|
" s.depth = float(params[2])\n",
|
|
" s.magnitude = float(params[3])\n",
|
|
" s.strike = float(params[4])\n",
|
|
" s.dip = float(params[5])\n",
|
|
" s.rake = float(params[6])\n",
|
|
" s.time = float(event.time - params[7])\n",
|
|
" return source\n",
|
|
"\n",
|
|
"def process_trace(trace, tmin, tmax, lowpass=False, inplace=True):\n",
|
|
" if lowpass:\n",
|
|
" trace.lowpass(4, f_low)\n",
|
|
" trace = trace.chop(tmin, tmax, inplace=inplace)\n",
|
|
" trace.taper(taper)\n",
|
|
" return trace\n",
|
|
"\n",
|
|
"iiter = 0\n",
|
|
"\n",
|
|
"def trace_fit(params, line=None):\n",
|
|
" global iiter\n",
|
|
" update_source(params)\n",
|
|
"\n",
|
|
" # Forward model synthetic seismograms\n",
|
|
" response = engine.process(source, targets)\n",
|
|
" syn_traces = response.pyrocko_traces()\n",
|
|
"\n",
|
|
" misfits = 0.\n",
|
|
" norms = 0.\n",
|
|
"\n",
|
|
" for obs, syn, target in zip(traces, syn_traces, targets):\n",
|
|
" syn_phs = store.t(phase, base_source, target)\n",
|
|
" \n",
|
|
" tmin = base_source.time + syn_phs - tmin_fit # start before theor. arrival\n",
|
|
" tmax = base_source.time + syn_phs + tmax_fit # end after theor. arrival\n",
|
|
" \n",
|
|
" syn = process_trace(syn, tmin, tmax)\n",
|
|
" obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=True)\n",
|
|
"\n",
|
|
" misfits += num.sqrt(num.sum((obs.ydata - syn.ydata)**2))\n",
|
|
" norms += num.sqrt(num.sum(obs.ydata**2))\n",
|
|
" \n",
|
|
" misfit = num.sqrt(misfits**2 / norms**2)\n",
|
|
" \n",
|
|
" iiter += 1\n",
|
|
"\n",
|
|
" if line:\n",
|
|
" data = {\n",
|
|
" 'y': [misfit],\n",
|
|
" 'x': [iiter],\n",
|
|
" }\n",
|
|
" line.data_source.stream(data)\n",
|
|
"\n",
|
|
" return misfit"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Running the optimization and plotting of the Convergence\n",
|
|
"For plotting we use bokeh (which you might need to install: `pip3 install bokeh`) \n",
|
|
"Jupyter Lab also requires the Bokeh extension: `jupyter labextension install jupyterlab_bokeh` \n",
|
|
"More info at https://bokeh.pydata.org/en/latest/docs/user_guide/notebook.html"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
" <div class=\"bk-root\">\n",
|
|
" <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
|
|
" <span id=\"1098\">Loading BokehJS ...</span>\n",
|
|
" </div>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"\n",
|
|
"(function(root) {\n",
|
|
" function now() {\n",
|
|
" return new Date();\n",
|
|
" }\n",
|
|
"\n",
|
|
" var force = true;\n",
|
|
"\n",
|
|
" if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n",
|
|
" root._bokeh_onload_callbacks = [];\n",
|
|
" root._bokeh_is_loading = undefined;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var JS_MIME_TYPE = 'application/javascript';\n",
|
|
" var HTML_MIME_TYPE = 'text/html';\n",
|
|
" var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
|
|
" var CLASS_NAME = 'output_bokeh rendered_html';\n",
|
|
"\n",
|
|
" /**\n",
|
|
" * Render data to the DOM node\n",
|
|
" */\n",
|
|
" function render(props, node) {\n",
|
|
" var script = document.createElement(\"script\");\n",
|
|
" node.appendChild(script);\n",
|
|
" }\n",
|
|
"\n",
|
|
" /**\n",
|
|
" * Handle when an output is cleared or removed\n",
|
|
" */\n",
|
|
" function handleClearOutput(event, handle) {\n",
|
|
" var cell = handle.cell;\n",
|
|
"\n",
|
|
" var id = cell.output_area._bokeh_element_id;\n",
|
|
" var server_id = cell.output_area._bokeh_server_id;\n",
|
|
" // Clean up Bokeh references\n",
|
|
" if (id != null && id in Bokeh.index) {\n",
|
|
" Bokeh.index[id].model.document.clear();\n",
|
|
" delete Bokeh.index[id];\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (server_id !== undefined) {\n",
|
|
" // Clean up Bokeh references\n",
|
|
" var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
|
|
" cell.notebook.kernel.execute(cmd, {\n",
|
|
" iopub: {\n",
|
|
" output: function(msg) {\n",
|
|
" var id = msg.content.text.trim();\n",
|
|
" if (id in Bokeh.index) {\n",
|
|
" Bokeh.index[id].model.document.clear();\n",
|
|
" delete Bokeh.index[id];\n",
|
|
" }\n",
|
|
" }\n",
|
|
" }\n",
|
|
" });\n",
|
|
" // Destroy server and session\n",
|
|
" var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
|
|
" cell.notebook.kernel.execute(cmd);\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" /**\n",
|
|
" * Handle when a new output is added\n",
|
|
" */\n",
|
|
" function handleAddOutput(event, handle) {\n",
|
|
" var output_area = handle.output_area;\n",
|
|
" var output = handle.output;\n",
|
|
"\n",
|
|
" // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
|
|
" if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
|
|
" return\n",
|
|
" }\n",
|
|
"\n",
|
|
" var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
|
|
"\n",
|
|
" if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
|
|
" toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
|
|
" // store reference to embed id on output_area\n",
|
|
" output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
|
|
" }\n",
|
|
" if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
|
|
" var bk_div = document.createElement(\"div\");\n",
|
|
" bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
|
|
" var script_attrs = bk_div.children[0].attributes;\n",
|
|
" for (var i = 0; i < script_attrs.length; i++) {\n",
|
|
" toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
|
|
" }\n",
|
|
" // store reference to server id on output_area\n",
|
|
" output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" function register_renderer(events, OutputArea) {\n",
|
|
"\n",
|
|
" function append_mime(data, metadata, element) {\n",
|
|
" // create a DOM node to render to\n",
|
|
" var toinsert = this.create_output_subarea(\n",
|
|
" metadata,\n",
|
|
" CLASS_NAME,\n",
|
|
" EXEC_MIME_TYPE\n",
|
|
" );\n",
|
|
" this.keyboard_manager.register_events(toinsert);\n",
|
|
" // Render to node\n",
|
|
" var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
|
|
" render(props, toinsert[toinsert.length - 1]);\n",
|
|
" element.append(toinsert);\n",
|
|
" return toinsert\n",
|
|
" }\n",
|
|
"\n",
|
|
" /* Handle when an output is cleared or removed */\n",
|
|
" events.on('clear_output.CodeCell', handleClearOutput);\n",
|
|
" events.on('delete.Cell', handleClearOutput);\n",
|
|
"\n",
|
|
" /* Handle when a new output is added */\n",
|
|
" events.on('output_added.OutputArea', handleAddOutput);\n",
|
|
"\n",
|
|
" /**\n",
|
|
" * Register the mime type and append_mime function with output_area\n",
|
|
" */\n",
|
|
" OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
|
|
" /* Is output safe? */\n",
|
|
" safe: true,\n",
|
|
" /* Index of renderer in `output_area.display_order` */\n",
|
|
" index: 0\n",
|
|
" });\n",
|
|
" }\n",
|
|
"\n",
|
|
" // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
|
|
" if (root.Jupyter !== undefined) {\n",
|
|
" var events = require('base/js/events');\n",
|
|
" var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
|
|
"\n",
|
|
" if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
|
|
" register_renderer(events, OutputArea);\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" \n",
|
|
" if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
|
|
" root._bokeh_timeout = Date.now() + 5000;\n",
|
|
" root._bokeh_failed_load = false;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var NB_LOAD_WARNING = {'data': {'text/html':\n",
|
|
" \"<div style='background-color: #fdd'>\\n\"+\n",
|
|
" \"<p>\\n\"+\n",
|
|
" \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
|
|
" \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
|
|
" \"</p>\\n\"+\n",
|
|
" \"<ul>\\n\"+\n",
|
|
" \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
|
|
" \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
|
|
" \"</ul>\\n\"+\n",
|
|
" \"<code>\\n\"+\n",
|
|
" \"from bokeh.resources import INLINE\\n\"+\n",
|
|
" \"output_notebook(resources=INLINE)\\n\"+\n",
|
|
" \"</code>\\n\"+\n",
|
|
" \"</div>\"}};\n",
|
|
"\n",
|
|
" function display_loaded() {\n",
|
|
" var el = document.getElementById(\"1098\");\n",
|
|
" if (el != null) {\n",
|
|
" el.textContent = \"BokehJS is loading...\";\n",
|
|
" }\n",
|
|
" if (root.Bokeh !== undefined) {\n",
|
|
" if (el != null) {\n",
|
|
" el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
|
|
" }\n",
|
|
" } else if (Date.now() < root._bokeh_timeout) {\n",
|
|
" setTimeout(display_loaded, 100)\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
"\n",
|
|
" function run_callbacks() {\n",
|
|
" try {\n",
|
|
" root._bokeh_onload_callbacks.forEach(function(callback) {\n",
|
|
" if (callback != null)\n",
|
|
" callback();\n",
|
|
" });\n",
|
|
" } finally {\n",
|
|
" delete root._bokeh_onload_callbacks\n",
|
|
" }\n",
|
|
" console.debug(\"Bokeh: all callbacks have finished\");\n",
|
|
" }\n",
|
|
"\n",
|
|
" function load_libs(css_urls, js_urls, callback) {\n",
|
|
" if (css_urls == null) css_urls = [];\n",
|
|
" if (js_urls == null) js_urls = [];\n",
|
|
"\n",
|
|
" root._bokeh_onload_callbacks.push(callback);\n",
|
|
" if (root._bokeh_is_loading > 0) {\n",
|
|
" console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
|
|
" return null;\n",
|
|
" }\n",
|
|
" if (js_urls == null || js_urls.length === 0) {\n",
|
|
" run_callbacks();\n",
|
|
" return null;\n",
|
|
" }\n",
|
|
" console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
|
|
" root._bokeh_is_loading = css_urls.length + js_urls.length;\n",
|
|
"\n",
|
|
" function on_load() {\n",
|
|
" root._bokeh_is_loading--;\n",
|
|
" if (root._bokeh_is_loading === 0) {\n",
|
|
" console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n",
|
|
" run_callbacks()\n",
|
|
" }\n",
|
|
" }\n",
|
|
"\n",
|
|
" function on_error() {\n",
|
|
" console.error(\"failed to load \" + url);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for (var i = 0; i < css_urls.length; i++) {\n",
|
|
" var url = css_urls[i];\n",
|
|
" const element = document.createElement(\"link\");\n",
|
|
" element.onload = on_load;\n",
|
|
" element.onerror = on_error;\n",
|
|
" element.rel = \"stylesheet\";\n",
|
|
" element.type = \"text/css\";\n",
|
|
" element.href = url;\n",
|
|
" console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n",
|
|
" document.body.appendChild(element);\n",
|
|
" }\n",
|
|
"\n",
|
|
" for (var i = 0; i < js_urls.length; i++) {\n",
|
|
" var url = js_urls[i];\n",
|
|
" var element = document.createElement('script');\n",
|
|
" element.onload = on_load;\n",
|
|
" element.onerror = on_error;\n",
|
|
" element.async = false;\n",
|
|
" element.src = url;\n",
|
|
" console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
|
|
" document.head.appendChild(element);\n",
|
|
" }\n",
|
|
" };var element = document.getElementById(\"1098\");\n",
|
|
" if (element == null) {\n",
|
|
" console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1098' but no matching script tag was found. \")\n",
|
|
" return false;\n",
|
|
" }\n",
|
|
"\n",
|
|
" function inject_raw_css(css) {\n",
|
|
" const element = document.createElement(\"style\");\n",
|
|
" element.appendChild(document.createTextNode(css));\n",
|
|
" document.body.appendChild(element);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n",
|
|
" var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n",
|
|
"\n",
|
|
" var inline_js = [\n",
|
|
" function(Bokeh) {\n",
|
|
" Bokeh.set_log_level(\"info\");\n",
|
|
" },\n",
|
|
" \n",
|
|
" function(Bokeh) {\n",
|
|
" \n",
|
|
" },\n",
|
|
" function(Bokeh) {} // ensure no trailing comma for IE\n",
|
|
" ];\n",
|
|
"\n",
|
|
" function run_inline_js() {\n",
|
|
" \n",
|
|
" if ((root.Bokeh !== undefined) || (force === true)) {\n",
|
|
" for (var i = 0; i < inline_js.length; i++) {\n",
|
|
" inline_js[i].call(root, root.Bokeh);\n",
|
|
" }if (force === true) {\n",
|
|
" display_loaded();\n",
|
|
" }} else if (Date.now() < root._bokeh_timeout) {\n",
|
|
" setTimeout(run_inline_js, 100);\n",
|
|
" } else if (!root._bokeh_failed_load) {\n",
|
|
" console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
|
|
" root._bokeh_failed_load = true;\n",
|
|
" } else if (force !== true) {\n",
|
|
" var cell = $(document.getElementById(\"1098\")).parents('.cell').data().cell;\n",
|
|
" cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
|
|
" }\n",
|
|
"\n",
|
|
" }\n",
|
|
"\n",
|
|
" if (root._bokeh_is_loading === 0) {\n",
|
|
" console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
|
|
" run_inline_js();\n",
|
|
" } else {\n",
|
|
" load_libs(css_urls, js_urls, function() {\n",
|
|
" console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n",
|
|
" run_inline_js();\n",
|
|
" });\n",
|
|
" }\n",
|
|
"}(window));"
|
|
],
|
|
"application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"<div style='background-color: #fdd'>\\n\"+\n \"<p>\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"</p>\\n\"+\n \"<ul>\\n\"+\n \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n \"<li>use INLINE resources instead, as so:</li>\\n\"+\n \"</ul>\\n\"+\n \"<code>\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"</code>\\n\"+\n \"</div>\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1098\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1098\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1098' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1098\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));"
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
" <div class=\"bk-root\" id=\"a8b5fc8f-ed23-4097-aa5d-f731fcd61c93\" data-root-id=\"1099\"></div>\n"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"(function(root) {\n",
|
|
" function embed_document(root) {\n",
|
|
" \n",
|
|
" var docs_json = {\"7d7c42af-c8d3-4041-bd78-9a421faa097c\":{\"roots\":{\"references\":[{\"attributes\":{\"below\":[{\"id\":\"1110\",\"type\":\"LinearAxis\"}],\"center\":[{\"id\":\"1114\",\"type\":\"Grid\"},{\"id\":\"1119\",\"type\":\"Grid\"}],\"left\":[{\"id\":\"1115\",\"type\":\"LinearAxis\"}],\"plot_height\":300,\"plot_width\":800,\"renderers\":[{\"id\":\"1136\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"1100\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1126\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1102\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"1106\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1104\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"1108\",\"type\":\"LinearScale\"}},\"id\":\"1099\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1120\",\"type\":\"PanTool\"},{\"id\":\"1121\",\"type\":\"WheelZoomTool\"},{\"id\":\"1122\",\"type\":\"BoxZoomTool\"},{\"id\":\"1123\",\"type\":\"SaveTool\"},{\"id\":\"1124\",\"type\":\"ResetTool\"},{\"id\":\"1125\",\"type\":\"HelpTool\"}]},\"id\":\"1126\",\"type\":\"Toolbar\"},{\"attributes\":{\"source\":{\"id\":\"1133\",\"type\":\"ColumnDataSource\"}},\"id\":\"1137\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1133\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1134\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1135\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1137\",\"type\":\"CDSView\"}},\"id\":\"1136\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"axis_label\":\"Misfit\",\"formatter\":{\"id\":\"1150\",\"type\":\"BasicTickFormatter\"},\"ticker\":{\"id\":\"1116\",\"type\":\"BasicTicker\"}},\"id\":\"1115\",\"type\":\"LinearAxis\"},{\"attributes\":{\"axis_label\":\"# Iteration\",\"formatter\":{\"id\":\"1148\",\"type\":\"BasicTickFormatter\"},\"ticker\":{\"id\":\"1111\",\"type\":\"BasicTicker\"}},\"id\":\"1110\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"1125\",\"type\":\"HelpTool\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1153\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"1148\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"text\":\"SciPy Optimisation Progress\"},\"id\":\"1100\",\"type\":\"Title\"},{\"attributes\":{\"overlay\":{\"id\":\"1153\",\"type\":\"BoxAnnotation\"}},\"id\":\"1122\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"fill_color\":{\"value\":\"#1f77b4\"},\"line_color\":{\"value\":\"#1f77b4\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1134\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1151\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"1152\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null},\"id\":\"1102\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1116\",\"type\":\"BasicTicker\"},{\"attributes\":{},\"id\":\"1150\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1135\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1124\",\"type\":\"ResetTool\"},{\"attributes\":{\"dimension\":1,\"ticker\":{\"id\":\"1116\",\"type\":\"BasicTicker\"}},\"id\":\"1119\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1108\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"1111\",\"type\":\"BasicTicker\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[],\"y\":[]},\"selected\":{\"id\":\"1152\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1151\",\"type\":\"UnionRenderers\"}},\"id\":\"1133\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1121\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"callback\":null},\"id\":\"1104\",\"type\":\"DataRange1d\"},{\"attributes\":{},\"id\":\"1120\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"1123\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"1106\",\"type\":\"LinearScale\"},{\"attributes\":{\"ticker\":{\"id\":\"1111\",\"type\":\"BasicTicker\"}},\"id\":\"1114\",\"type\":\"Grid\"}],\"root_ids\":[\"1099\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n",
|
|
" var render_items = [{\"docid\":\"7d7c42af-c8d3-4041-bd78-9a421faa097c\",\"notebook_comms_target\":\"1154\",\"roots\":{\"1099\":\"a8b5fc8f-ed23-4097-aa5d-f731fcd61c93\"}}];\n",
|
|
" root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
|
|
"\n",
|
|
" }\n",
|
|
" if (root.Bokeh !== undefined) {\n",
|
|
" embed_document(root);\n",
|
|
" } else {\n",
|
|
" var attempts = 0;\n",
|
|
" var timer = setInterval(function(root) {\n",
|
|
" if (root.Bokeh !== undefined) {\n",
|
|
" embed_document(root);\n",
|
|
" clearInterval(timer);\n",
|
|
" }\n",
|
|
" attempts++;\n",
|
|
" if (attempts > 100) {\n",
|
|
" console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n",
|
|
" clearInterval(timer);\n",
|
|
" }\n",
|
|
" }, 10, root)\n",
|
|
" }\n",
|
|
"})(window);"
|
|
],
|
|
"application/vnd.bokehjs_exec.v0+json": ""
|
|
},
|
|
"metadata": {
|
|
"application/vnd.bokehjs_exec.v0+json": {
|
|
"id": "1099"
|
|
}
|
|
},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<p><code><Bokeh Notebook handle for <strong>In[13]</strong>></code></p>"
|
|
],
|
|
"text/plain": [
|
|
"<bokeh.io.notebook.CommsHandle at 0x7f1b61500dd8>"
|
|
]
|
|
},
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from bokeh.io import push_notebook, show, output_notebook\n",
|
|
"from bokeh.plotting import figure\n",
|
|
"output_notebook()\n",
|
|
"\n",
|
|
"f = figure(title='SciPy Optimisation Progress',\n",
|
|
" x_axis_label='# Iteration',\n",
|
|
" y_axis_label='Misfit',\n",
|
|
" plot_width=800,\n",
|
|
" plot_height=300)\n",
|
|
"plot = f.scatter([], [])\n",
|
|
"show(f, notebook_handle=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Optimisation with SciPy\n",
|
|
"We will use `scipy.optimize.differential_evolution` to find a best fitting model. The method is stochastic in nature (does not use gradient methods) to find the minimium, and can search large areas of candidate space, but often requires larger numbers of function evaluations than conventional gradient based techniques. The scipy solver can easily be exchanged for a method of your favor. If you just want a quick demonstration, you can change the number of maxiter in the solve function to something lower."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Time elapsed: 236.7 s\n",
|
|
"Best model:\n",
|
|
" - Misfit 1.124329\n",
|
|
"--- !pf.DCSource\n",
|
|
"lat: 42.29\n",
|
|
"lon: 13.35\n",
|
|
"north_shift: 14979.312574228847\n",
|
|
"east_shift: 1556.6646508341364\n",
|
|
"depth: 3000.685138774966\n",
|
|
"time: 2009-04-06 01:32:29.191294\n",
|
|
"stf_mode: post\n",
|
|
"magnitude: 6.200159644093804\n",
|
|
"strike: 103.63201050142605\n",
|
|
"dip: 59.783215252520336\n",
|
|
"rake: -148.26831683964517\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def solve():\n",
|
|
" t = time.time()\n",
|
|
"\n",
|
|
" result = scipy.optimize.differential_evolution(\n",
|
|
" trace_fit,\n",
|
|
" args=[plot],\n",
|
|
" bounds=tuple(bounds.values()),\n",
|
|
" maxiter=15000,\n",
|
|
" tol=0.01,\n",
|
|
" callback=lambda a, convergence: push_notebook())\n",
|
|
"\n",
|
|
" source = update_source(result.x)\n",
|
|
" source.regularize()\n",
|
|
"\n",
|
|
" print(\"Time elapsed: %.1f s\" % (time.time() - t))\n",
|
|
" print(\"Best model:\\n - Misfit %f\" % trace_fit(result.x))\n",
|
|
" print(source)\n",
|
|
" return result, source\n",
|
|
"\n",
|
|
"\n",
|
|
"# Start the optimisation\n",
|
|
"result, best_source = solve()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Plot the Results\n",
|
|
"Now we plot the synthetic waveforms produced by our the best model vs. the observed traces."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def plot_traces(result):\n",
|
|
" nstations = len(stations_list)\n",
|
|
" response = engine.process(source, targets)\n",
|
|
" syn_traces = response.pyrocko_traces()\n",
|
|
"\n",
|
|
" fig, axes = plt.subplots(nstations, squeeze=True, sharex=True)\n",
|
|
" fig.subplots_adjust(hspace=0)\n",
|
|
" plt.setp([ax.get_xticklabels() for ax in axes[:-1]], visible=False)\n",
|
|
"\n",
|
|
" for istation, (obs, syn, target) in enumerate(zip(traces, syn_traces, targets)):\n",
|
|
" ax = axes[istation]\n",
|
|
" tp = store.t(phase, base_source, target)\n",
|
|
" tp_onset = base_source.time + tp\n",
|
|
" tmin = tp_onset - tmin_fit\n",
|
|
" tmax = tp_onset + tmax_fit\n",
|
|
" \n",
|
|
" syn = process_trace(syn, tmin, tmax)\n",
|
|
" obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=False)\n",
|
|
" \n",
|
|
" s1 = ax.plot(obs.get_xdata(), obs.ydata, color='b')\n",
|
|
" s2 = ax.plot(syn.get_xdata(), syn.ydata, color='r')\n",
|
|
" s3 = ax.plot([tp_onset, tp_onset], [tr.ydata.min(), tr.ydata.max()], 'k-', lw=2)\n",
|
|
"\n",
|
|
" ax.text(-.2, 0.5, stations_list[istation].station,\n",
|
|
" transform=ax.transAxes)\n",
|
|
" ax.set_yticklabels([], visible=False)\n",
|
|
"\n",
|
|
" axes[-1].set_xlabel('Time [s]')\n",
|
|
" plt.suptitle('Waveform fits for %s-Phase and component %s' % (phase, component))\n",
|
|
" plt.legend(\n",
|
|
" (s1[0], s2[0], s3[0]),\n",
|
|
" ('Data', 'Synthetic','%s Phase-onset' % phase),\n",
|
|
" loc='upper center',\n",
|
|
" bbox_to_anchor=(0.5, -2.),\n",
|
|
" fancybox=True, shadow=True, ncol=5)\n",
|
|
" \n",
|
|
" plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def plot_snuffler(result, source):\n",
|
|
" engine = gf.get_engine()\n",
|
|
" response = engine.process(source, targets)\n",
|
|
" syn_traces = response.pyrocko_traces()\n",
|
|
" obs_traces = []\n",
|
|
" \n",
|
|
" for obs, syn, target in zip(traces, syn_traces, targets):\n",
|
|
" tp = store.t('P', base_source, target)\n",
|
|
" tmin = base_source.time + tp - tmin_fit\n",
|
|
" tmax = base_source.time + tp + tmax_fit\n",
|
|
"\n",
|
|
" syn = process_trace(syn, tmin, tmax)\n",
|
|
" obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=False)\n",
|
|
"\n",
|
|
" obs_traces.append(obs)\n",
|
|
"\n",
|
|
" trace.snuffle(obs_traces + syn_traces, stations=stations_list, events= [event])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Next we plot the station distribution with folium (which you might need to install)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2NvZGUuanF1ZXJ5LmNvbS9qcXVlcnktMS4xMi40Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS40LjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdjZG4uZ2l0aGFjay5jb20vcHl0aG9uLXZpc3VhbGl6YXRpb24vZm9saXVtL21hc3Rlci9mb2xpdW0vdGVtcGxhdGVzL2xlYWZsZXQuYXdlc29tZS5yb3RhdGUuY3NzIi8+CiAgICA8c3R5bGU+aHRtbCwgYm9keSB7d2lkdGg6IDEwMCU7aGVpZ2h0OiAxMDAlO21hcmdpbjogMDtwYWRkaW5nOiAwO308L3N0eWxlPgogICAgPHN0eWxlPiNtYXAge3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO2JvdHRvbTowO3JpZ2h0OjA7bGVmdDowO308L3N0eWxlPgogICAgCiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLAogICAgICAgIGluaXRpYWwtc2NhbGU9MS4wLCBtYXhpbXVtLXNjYWxlPTEuMCwgdXNlci1zY2FsYWJsZT1ubyIgLz4KICAgIDxzdHlsZT4jbWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1IHsKICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7CiAgICAgICAgd2lkdGg6IDEwMC4wJTsKICAgICAgICBoZWlnaHQ6IDEwMC4wJTsKICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgIHRvcDogMC4wJTsKICAgICAgICB9CiAgICA8L3N0eWxlPgo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgPGRpdiBjbGFzcz0iZm9saXVtLW1hcCIgaWQ9Im1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSIgPjwvZGl2Pgo8L2JvZHk+CjxzY3JpcHQ+ICAgIAogICAgCiAgICAKICAgICAgICB2YXIgYm91bmRzID0gbnVsbDsKICAgIAoKICAgIHZhciBtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUgPSBMLm1hcCgKICAgICAgICAnbWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1JywgewogICAgICAgIGNlbnRlcjogWzQyLjI5LCAxMy4zNV0sCiAgICAgICAgem9vbTogMywKICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICBsYXllcnM6IFtdLAogICAgICAgIHdvcmxkQ29weUp1bXA6IGZhbHNlLAogICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcsCiAgICAgICAgem9vbUNvbnRyb2w6IHRydWUsCiAgICAgICAgfSk7CgoKICAgIAogICAgdmFyIHRpbGVfbGF5ZXJfNmE3NDcwYTk5OTk5NGEzNDk5Njk3YWQwN2JhNTM2YTYgPSBMLnRpbGVMYXllcigKICAgICAgICAnaHR0cHM6Ly9zdGFtZW4tdGlsZXMte3N9LmEuc3NsLmZhc3RseS5uZXQvdGVycmFpbi97en0ve3h9L3t5fS5qcGcnLAogICAgICAgIHsKICAgICAgICAiYXR0cmlidXRpb24iOiBudWxsLAogICAgICAgICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAgICAgICAibWF4TmF0aXZlWm9vbSI6IDE4LAogICAgICAgICJtYXhab29tIjogMTgsCiAgICAgICAgIm1pblpvb20iOiAwLAogICAgICAgICJub1dyYXAiOiBmYWxzZSwKICAgICAgICAib3BhY2l0eSI6IDEsCiAgICAgICAgInN1YmRvbWFpbnMiOiAiYWJjIiwKICAgICAgICAidG1zIjogZmFsc2UKfSkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgIAogICAgICAgIHZhciBtYXJrZXJfZmEwYzhlNmM1NzAwNDMzYjlkMWI0NzVjNDhjYzQxNTYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzQyLjI5LCAxMy4zNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKCiAgICAgICAgICAgICAgICB2YXIgaWNvbl84N2Y5NjIxZWJlNDI0NmRlYTEyNWYzYzA4Y2EyMDk1NyA9IEwuQXdlc29tZU1hcmtlcnMuaWNvbih7CiAgICAgICAgICAgICAgICAgICAgaWNvbjogJ2luZm8tc2lnbicsCiAgICAgICAgICAgICAgICAgICAgaWNvbkNvbG9yOiAnd2hpdGUnLAogICAgICAgICAgICAgICAgICAgIG1hcmtlckNvbG9yOiAncmVkJywKICAgICAgICAgICAgICAgICAgICBwcmVmaXg6ICdnbHlwaGljb24nLAogICAgICAgICAgICAgICAgICAgIGV4dHJhQ2xhc3NlczogJ2ZhLXJvdGF0ZS0wJwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgbWFya2VyX2ZhMGM4ZTZjNTcwMDQzM2I5ZDFiNDc1YzQ4Y2M0MTU2LnNldEljb24oaWNvbl84N2Y5NjIxZWJlNDI0NmRlYTEyNWYzYzA4Y2EyMDk1Nyk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hNDQxMThlNTAyN2E0MGJiYjNlNzU1NTk1ODMxNjE3OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84ZGUwMzk0Mjg1ODk0MmY2YTI4YmQ4ODM1NGE0YTA0YSA9ICQoYDxkaXYgaWQ9Imh0bWxfOGRlMDM5NDI4NTg5NDJmNmEyOGJkODgzNTRhNGEwNGEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjIwMDkgQXF1aWxhIEVhcnRocXVha2U8L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E0NDExOGU1MDI3YTQwYmJiM2U3NTU1OTU4MzE2MTc4LnNldENvbnRlbnQoaHRtbF84ZGUwMzk0Mjg1ODk0MmY2YTI4YmQ4ODM1NGE0YTA0YSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2ZhMGM4ZTZjNTcwMDQzM2I5ZDFiNDc1YzQ4Y2M0MTU2LmJpbmRQb3B1cChwb3B1cF9hNDQxMThlNTAyN2E0MGJiYjNlNzU1NTk1ODMxNjE3OCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzZkNWQzZDRhNTA4NTQ1ODhiNTVjYTA1YjU1MjY3YTVkID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs2NS41NTk4LCAtMTY3LjkyNjddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wNGZjYzhjZmNkMzQ0NzVjYWYwNzFhYjY1OGMyY2QzMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hMGJhYzBjZjBlOGE0NzdkOWE5NTIxZWFlYmNkMmQxOSA9ICQoYDxkaXYgaWQ9Imh0bWxfYTBiYWMwY2YwZThhNDc3ZDlhOTUyMWVhZWJjZDJkMTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlROQTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDRmY2M4Y2ZjZDM0NDc1Y2FmMDcxYWI2NThjMmNkMzIuc2V0Q29udGVudChodG1sX2EwYmFjMGNmMGU4YTQ3N2Q5YTk1MjFlYWViY2QyZDE5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNmQ1ZDNkNGE1MDg1NDU4OGI1NWNhMDViNTUyNjdhNWQuYmluZFBvcHVwKHBvcHVwXzA0ZmNjOGNmY2QzNDQ3NWNhZjA3MWFiNjU4YzJjZDMyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNGVlODhmOWE4MmFiNDFhYjg5YmM5OGJiYjZkODA0YTcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzU1LjQ2ODk0LCAtMTMzLjEyMjk3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTU5ZjQyNDQ0ODFjNDkyOGE0MGY0Mjk3NDQ0YWJkMzEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWZlMWNiYmE4ZjI2NDZiNWI3ZmE3NTU0NDc4OWI5ZDUgPSAkKGA8ZGl2IGlkPSJodG1sXzFmZTFjYmJhOGYyNjQ2YjViN2ZhNzU1NDQ3ODliOWQ1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5DUkFHPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xNTlmNDI0NDQ4MWM0OTI4YTQwZjQyOTc0NDRhYmQzMS5zZXRDb250ZW50KGh0bWxfMWZlMWNiYmE4ZjI2NDZiNWI3ZmE3NTU0NDc4OWI5ZDUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80ZWU4OGY5YTgyYWI0MWFiODliYzk4YmJiNmQ4MDRhNy5iaW5kUG9wdXAocG9wdXBfMTU5ZjQyNDQ0ODFjNDkyOGE0MGY0Mjk3NDQ0YWJkMzEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9lMWM2ZjRhZTJjOGM0MmY2YTE2NWY3OWJhNTlmZmI5YyA9IEwubWFya2VyKAogICAgICAgICAgICBbNDkuMjU2LCAtNTcuNTA0Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU0MTQxNzBjMzkxMTQzZDVhM2NjMzA3NmJiNDQ3MzU4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBkNmYxMjI2OWIwODRjNjU4NDA5NDkwYjJkMjVhM2NjID0gJChgPGRpdiBpZD0iaHRtbF8wZDZmMTIyNjliMDg0YzY1ODQwOTQ5MGIyZDI1YTNjYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+RFJMTjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNTQxNDE3MGMzOTExNDNkNWEzY2MzMDc2YmI0NDczNTguc2V0Q29udGVudChodG1sXzBkNmYxMjI2OWIwODRjNjU4NDA5NDkwYjJkMjVhM2NjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZTFjNmY0YWUyYzhjNDJmNmExNjVmNzliYTU5ZmZiOWMuYmluZFBvcHVwKHBvcHVwXzU0MTQxNzBjMzkxMTQzZDVhM2NjMzA3NmJiNDQ3MzU4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNjdmZjJjY2M1YjRiNGRiNjkxMDgwNGY4NTUwMDRiNDkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzY4LjMwNjUsIC0xMzMuNTI1NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzgzNDYxYWM4Zjk2YTRlYzQ5NTY0NTdhMzA1NTQwZDY3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2QxMDY4ZDVkZmI0NTQ3MjZiYjczYWVlZmRjOWM1NzRmID0gJChgPGRpdiBpZD0iaHRtbF9kMTA2OGQ1ZGZiNDU0NzI2YmI3M2FlZWZkYzljNTc0ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+SU5LPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84MzQ2MWFjOGY5NmE0ZWM0OTU2NDU3YTMwNTU0MGQ2Ny5zZXRDb250ZW50KGh0bWxfZDEwNjhkNWRmYjQ1NDcyNmJiNzNhZWVmZGM5YzU3NGYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82N2ZmMmNjYzViNGI0ZGI2OTEwODA0Zjg1NTAwNGI0OS5iaW5kUG9wdXAocG9wdXBfODM0NjFhYzhmOTZhNGVjNDk1NjQ1N2EzMDU1NDBkNjcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8wMTcyZDJhOTgyNmQ0Zjc3OTgwMzY4Y2Q5ODJhMGQyNSA9IEwubWFya2VyKAogICAgICAgICAgICBbNzQuNjg5MiwgLTk0Ljg5NjJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85OTRmYzdiMmQyODc0ZTNlODE2YzhmODY1N2EzMzc1YSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iMmRiODljYzJlYWI0ZjgzYmEzOTIyNjRkZGIwZmEyYyA9ICQoYDxkaXYgaWQ9Imh0bWxfYjJkYjg5Y2MyZWFiNGY4M2JhMzkyMjY0ZGRiMGZhMmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlJFUzwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTk0ZmM3YjJkMjg3NGUzZTgxNmM4Zjg2NTdhMzM3NWEuc2V0Q29udGVudChodG1sX2IyZGI4OWNjMmVhYjRmODNiYTM5MjI2NGRkYjBmYTJjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMDE3MmQyYTk4MjZkNGY3Nzk4MDM2OGNkOTgyYTBkMjUuYmluZFBvcHVwKHBvcHVwXzk5NGZjN2IyZDI4NzRlM2U4MTZjOGY4NjU3YTMzNzVhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMDU0NTliNzllZjY4NDQ4N2I0ODJiOGFhNGExODRmNTAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE3LjY2ODUzLCAtNjEuNzg1NTddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iYmMwYTJkMzQ2MjA0ZjY0OTc1MDAyN2Q5YmFiM2I0NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81ZjE4ZTY0YWU0OGM0ZWRlYjBhMjU2OGQ4NWNlMzEwOSA9ICQoYDxkaXYgaWQ9Imh0bWxfNWYxOGU2NGFlNDhjNGVkZWIwYTI1NjhkODVjZTMxMDkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkFOV0I8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2JiYzBhMmQzNDYyMDRmNjQ5NzUwMDI3ZDliYWIzYjQ3LnNldENvbnRlbnQoaHRtbF81ZjE4ZTY0YWU0OGM0ZWRlYjBhMjU2OGQ4NWNlMzEwOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzA1NDU5Yjc5ZWY2ODQ0ODdiNDgyYjhhYTRhMTg0ZjUwLmJpbmRQb3B1cChwb3B1cF9iYmMwYTJkMzQ2MjA0ZjY0OTc1MDAyN2Q5YmFiM2I0NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzBmODE2ZWRjMDlkODQzM2Q4ZjVkMGQ2MTAwNDk2MmM1ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsyMS41MTE0OSwgLTcxLjEzMjddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hY2ZlYWM4NDIzMzY0ZjhjYmQ3ZmIxZjFlZjNjMGIxZCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNDRmYmMxZDI3YjM0ZTk2OWI4M2YwMTYwZDJmMzdhYSA9ICQoYDxkaXYgaWQ9Imh0bWxfMzQ0ZmJjMWQyN2IzNGU5NjliODNmMDE2MGQyZjM3YWEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkdSVEs8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FjZmVhYzg0MjMzNjRmOGNiZDdmYjFmMWVmM2MwYjFkLnNldENvbnRlbnQoaHRtbF8zNDRmYmMxZDI3YjM0ZTk2OWI4M2YwMTYwZDJmMzdhYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzBmODE2ZWRjMDlkODQzM2Q4ZjVkMGQ2MTAwNDk2MmM1LmJpbmRQb3B1cChwb3B1cF9hY2ZlYWM4NDIzMzY0ZjhjYmQ3ZmIxZjFlZjNjMGIxZCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2I3N2MxNjgzZDBkOTRlNDZhNWU4NmJmYjgxZTE2OWU0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsxOC4yMjYwNSwgLTc3LjUzNDU0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzFhOWFiYTNhNWM5NGRiYmI0MGJmYTYyMDdkOWQ2M2IgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDYwOWUwMDA1OTU3NGNmOGIyZWY0MWVhNDliNjc2NDAgPSAkKGA8ZGl2IGlkPSJodG1sXzQ2MDllMDAwNTk1NzRjZjhiMmVmNDFlYTQ5YjY3NjQwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5NVERKPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83MWE5YWJhM2E1Yzk0ZGJiYjQwYmZhNjIwN2Q5ZDYzYi5zZXRDb250ZW50KGh0bWxfNDYwOWUwMDA1OTU3NGNmOGIyZWY0MWVhNDliNjc2NDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9iNzdjMTY4M2QwZDk0ZTQ2YTVlODZiZmI4MWUxNjllNC5iaW5kUG9wdXAocG9wdXBfNzFhOWFiYTNhNWM5NGRiYmI0MGJmYTYyMDdkOWQ2M2IpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85Y2YyMjNhY2E3Y2I0OWZhODVkODMwMDE2NjNmZjJhMiA9IEwubWFya2VyKAogICAgICAgICAgICBbMTQuMzkyMDIsIC0xNi45NTU0N10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk1ZDFjZDRiZDc4MjQwZGI4ZmQ2OTk1NGYwMzkxNmE4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Y5OGMzZDhlNTdiYzRiMjNhYzViN2Y2M2M0ZTIxZTc4ID0gJChgPGRpdiBpZD0iaHRtbF9mOThjM2Q4ZTU3YmM0YjIzYWM1YjdmNjNjNGUyMWU3OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TUJPPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85NWQxY2Q0YmQ3ODI0MGRiOGZkNjk5NTRmMDM5MTZhOC5zZXRDb250ZW50KGh0bWxfZjk4YzNkOGU1N2JjNGIyM2FjNWI3ZjYzYzRlMjFlNzgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl85Y2YyMjNhY2E3Y2I0OWZhODVkODMwMDE2NjNmZjJhMi5iaW5kUG9wdXAocG9wdXBfOTVkMWNkNGJkNzgyNDBkYjhmZDY5OTU0ZjAzOTE2YTgpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8xNzBkNWY5ZTUxNTI0YmFkYmM1M2Y0ZDExN2JlMTFiZSA9IEwubWFya2VyKAogICAgICAgICAgICBbNzguOTE1NCwgMTEuOTM4NV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzUyYTA5YWE5MjE1MjRjMWE4NTFiNjAxNWYxM2YxYWQ3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk1ZTc3MWMzYWI5NDQzOWRiMmY2OTViYzZkYjg3ZTFmID0gJChgPGRpdiBpZD0iaHRtbF85NWU3NzFjM2FiOTQ0MzlkYjJmNjk1YmM2ZGI4N2UxZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+S0JTPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81MmEwOWFhOTIxNTI0YzFhODUxYjYwMTVmMTNmMWFkNy5zZXRDb250ZW50KGh0bWxfOTVlNzcxYzNhYjk0NDM5ZGIyZjY5NWJjNmRiODdlMWYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xNzBkNWY5ZTUxNTI0YmFkYmM1M2Y0ZDExN2JlMTFiZS5iaW5kUG9wdXAocG9wdXBfNTJhMDlhYTkyMTUyNGMxYTg1MWI2MDE1ZjEzZjFhZDcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kNjkyY2FhOWE2YWQ0NzdiYjJiNWFjNGU4ODA0ZmEzZSA9IEwubWFya2VyKAogICAgICAgICAgICBbLTEuMTI2OCwgMzcuMjUyM10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2MyMTI4MTE5OTJkNjQ0YTI4YzRhNzRkZTNkZGY0NjQyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc1MzQyMjg2OGFlMDQ5NzFhZGY2YmNlNjNlZmUzYTU2ID0gJChgPGRpdiBpZD0iaHRtbF83NTM0MjI4NjhhZTA0OTcxYWRmNmJjZTYzZWZlM2E1NiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+S01CTzwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzIxMjgxMTk5MmQ2NDRhMjhjNGE3NGRlM2RkZjQ2NDIuc2V0Q29udGVudChodG1sXzc1MzQyMjg2OGFlMDQ5NzFhZGY2YmNlNjNlZmUzYTU2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZDY5MmNhYTlhNmFkNDc3YmIyYjVhYzRlODgwNGZhM2UuYmluZFBvcHVwKHBvcHVwX2MyMTI4MTE5OTJkNjQ0YTI4YzRhNzRkZTNkZGY0NjQyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYjYzMjI3MzdkZTlkNGNhMTg4NTM0ZGYxMDFiZTBhNzMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzUuMjI4OCwgOTYuOTQ3Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzYxOTllYmU0ZTc2YzQwMjZiMDA5YjI5MDBlMzE4YjQxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc3YWRmMjA0M2Y2ZDQ5MGNiMDE3MTUyYzIwYjk3NDc5ID0gJChgPGRpdiBpZD0iaHRtbF83N2FkZjIwNDNmNmQ0OTBjYjAxNzE1MmMyMGI5NzQ3OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TEhNSTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjE5OWViZTRlNzZjNDAyNmIwMDliMjkwMGUzMThiNDEuc2V0Q29udGVudChodG1sXzc3YWRmMjA0M2Y2ZDQ5MGNiMDE3MTUyYzIwYjk3NDc5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYjYzMjI3MzdkZTlkNGNhMTg4NTM0ZGYxMDFiZTBhNzMuYmluZFBvcHVwKHBvcHVwXzYxOTllYmU0ZTc2YzQwMjZiMDA5YjI5MDBlMzE4YjQxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMjAwZmU2Mzk2NmRiNDM5OGJkNTNjYWI1ODk4ZWQxMTYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWy0yNi4zMzA2NiwgLTU3LjMzMDk1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjQyNGJiODAzNjUyNGE5Mzg5MjdmMGNiMDdkNjZkZjMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTViNjczOTg2Y2UyNDRiZmEyM2QxODZlODNmNTJlYWMgPSAkKGA8ZGl2IGlkPSJodG1sXzE1YjY3Mzk4NmNlMjQ0YmZhMjNkMTg2ZTgzZjUyZWFjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5DUFVQPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNDI0YmI4MDM2NTI0YTkzODkyN2YwY2IwN2Q2NmRmMy5zZXRDb250ZW50KGh0bWxfMTViNjczOTg2Y2UyNDRiZmEyM2QxODZlODNmNTJlYWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8yMDBmZTYzOTY2ZGI0Mzk4YmQ1M2NhYjU4OThlZDExNi5iaW5kUG9wdXAocG9wdXBfYjQyNGJiODAzNjUyNGE5Mzg5MjdmMGNiMDdkNjZkZjMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jNWFlYTNlN2UxM2M0ZjUzYTIyYzhlMzc4YzY2OGU2ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbNi42NzAxNiwgLTQuODU2NTZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83NWQ0NWZmYzZjZTY0ZWZmODI1NzJlNWZkZWEwZmZiNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mMWUyZDdmNjgzMTk0M2UwYTMxNmE4ZmNiNTBlODdkZCA9ICQoYDxkaXYgaWQ9Imh0bWxfZjFlMmQ3ZjY4MzE5NDNlMGEzMTZhOGZjYjUwZTg3ZGQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkRCSUM8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc1ZDQ1ZmZjNmNlNjRlZmY4MjU3MmU1ZmRlYTBmZmI1LnNldENvbnRlbnQoaHRtbF9mMWUyZDdmNjgzMTk0M2UwYTMxNmE4ZmNiNTBlODdkZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2M1YWVhM2U3ZTEzYzRmNTNhMjJjOGUzNzhjNjY4ZTZlLmJpbmRQb3B1cChwb3B1cF83NWQ0NWZmYzZjZTY0ZWZmODI1NzJlNWZkZWEwZmZiNSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzNlYjNhMDVmZDM3NTQ0ZDBiODc2OTNjN2Y1YzJmY2RlID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0MC4wMTgzLCAxMTYuMTY3OV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFmZWZjOGQzMjgwMzQ3NjZiNmUxZmY4YWNmNDRmZTRkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2ZkOTkxZTA0ZTJjODQzZmJiMWViMTllNjc1NjkwZmRiID0gJChgPGRpdiBpZD0iaHRtbF9mZDk5MWUwNGUyYzg0M2ZiYjFlYjE5ZTY3NTY5MGZkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QkpUPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xZmVmYzhkMzI4MDM0NzY2YjZlMWZmOGFjZjQ0ZmU0ZC5zZXRDb250ZW50KGh0bWxfZmQ5OTFlMDRlMmM4NDNmYmIxZWIxOWU2NzU2OTBmZGIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zZWIzYTA1ZmQzNzU0NGQwYjg3NjkzYzdmNWMyZmNkZS5iaW5kUG9wdXAocG9wdXBfMWZlZmM4ZDMyODAzNDc2NmI2ZTFmZjhhY2Y0NGZlNGQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kYTg0ZTE1YTY0MTY0NmZjYmNhYWJjODQwNzhmOTQzZiA9IEwubWFya2VyKAogICAgICAgICAgICBbNDkuMjcwNCwgMTE5Ljc0MTRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83ODdlOTFjNWU0MjA0MTA3ODU3MDIwMjFjNDM1MjlkOCA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MjdhMTNmZmIyZjE0NGE1OWE0Yzk0NDEwMzUzNTI2MCA9ICQoYDxkaXYgaWQ9Imh0bWxfNTI3YTEzZmZiMmYxNDRhNTlhNGM5NDQxMDM1MzUyNjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkhJQTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzg3ZTkxYzVlNDIwNDEwNzg1NzAyMDIxYzQzNTI5ZDguc2V0Q29udGVudChodG1sXzUyN2ExM2ZmYjJmMTQ0YTU5YTRjOTQ0MTAzNTM1MjYwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZGE4NGUxNWE2NDE2NDZmY2JjYWFiYzg0MDc4Zjk0M2YuYmluZFBvcHVwKHBvcHVwXzc4N2U5MWM1ZTQyMDQxMDc4NTcwMjAyMWM0MzUyOWQ4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfODU4MWVmMjE3ODY5NDA4NTgzNzI0NTVmYWVhMjZlN2MgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI1LjEyMzMsIDEwMi43NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E4OGUxZWIwODE1ZDRjNWU5ZTBiODQ4YjYxMTYyNDJkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI0MmIxYTNiYWMwNjQwYWY4NDVhMGI4ZGFmZDBkN2M0ID0gJChgPGRpdiBpZD0iaHRtbF8yNDJiMWEzYmFjMDY0MGFmODQ1YTBiOGRhZmQwZDdjNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+S01JPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hODhlMWViMDgxNWQ0YzVlOWUwYjg0OGI2MTE2MjQyZC5zZXRDb250ZW50KGh0bWxfMjQyYjFhM2JhYzA2NDBhZjg0NWEwYjhkYWZkMGQ3YzQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84NTgxZWYyMTc4Njk0MDg1ODM3MjQ1NWZhZWEyNmU3Yy5iaW5kUG9wdXAocG9wdXBfYTg4ZTFlYjA4MTVkNGM1ZTllMGI4NDhiNjExNjI0MmQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mZDg0ZTcwMjQ4ZWI0ZjQ4OGYyMTEzMmNhNDU3OGM5YiA9IEwubWFya2VyKAogICAgICAgICAgICBbMTkuMDI5MSwgMTA5Ljg0NDVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lNDRlOThlMjk4ZjQ0ZGNiOGM5MmY4M2ZhNmNkZDRlNiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81ZmQ4MDY4MWE3NjA0NjA3YThhMTY0ZjAwZmE2NWE2YyA9ICQoYDxkaXYgaWQ9Imh0bWxfNWZkODA2ODFhNzYwNDYwN2E4YTE2NGYwMGZhNjVhNmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlFJWjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTQ0ZTk4ZTI5OGY0NGRjYjhjOTJmODNmYTZjZGQ0ZTYuc2V0Q29udGVudChodG1sXzVmZDgwNjgxYTc2MDQ2MDdhOGExNjRmMDBmYTY1YTZjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZmQ4NGU3MDI0OGViNGY0ODhmMjExMzJjYTQ1NzhjOWIuYmluZFBvcHVwKHBvcHVwX2U0NGU5OGUyOThmNDRkY2I4YzkyZjgzZmE2Y2RkNGU2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYTUxZGMwZjU5MWI0NGNmNmFmZGE1N2Y1ODg3NTIwMmYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzMxLjA5NDgsIDEyMS4xOTA4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODMzZGU1MGRiMjBmNDFhYzgzZDZkMjQ2NzA3OGU3NTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMmM1NzNmMGQzYTY0NDUzNTg3N2Q3Yjg5M2MwNDQxMDAgPSAkKGA8ZGl2IGlkPSJodG1sXzJjNTczZjBkM2E2NDQ1MzU4NzdkN2I4OTNjMDQ0MTAwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TU0U8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzgzM2RlNTBkYjIwZjQxYWM4M2Q2ZDI0NjcwNzhlNzUwLnNldENvbnRlbnQoaHRtbF8yYzU3M2YwZDNhNjQ0NTM1ODc3ZDdiODkzYzA0NDEwMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2E1MWRjMGY1OTFiNDRjZjZhZmRhNTdmNTg4NzUyMDJmLmJpbmRQb3B1cChwb3B1cF84MzNkZTUwZGIyMGY0MWFjODNkNmQyNDY3MDc4ZTc1MCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2QwYmM3YjkxYzJkYTQwZjI4ODc2ZTQxM2QyZWNiYWEyID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0My44MTM4LCA4Ny43MDQ5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTBkNmVhNDlkNGNlNDg4ODhjMjVhNjk2OTM1M2U3MmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOWZkYzY1ODYyYmI4NGVjODkyYzEzNTY2YjQ0NDE3MDUgPSAkKGA8ZGl2IGlkPSJodG1sXzlmZGM2NTg2MmJiODRlYzg5MmMxMzU2NmI0NDQxNzA1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5XTVE8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzEwZDZlYTQ5ZDRjZTQ4ODg4YzI1YTY5NjkzNTNlNzJmLnNldENvbnRlbnQoaHRtbF85ZmRjNjU4NjJiYjg0ZWM4OTJjMTM1NjZiNDQ0MTcwNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2QwYmM3YjkxYzJkYTQwZjI4ODc2ZTQxM2QyZWNiYWEyLmJpbmRQb3B1cChwb3B1cF8xMGQ2ZWE0OWQ0Y2U0ODg4OGMyNWE2OTY5MzUzZTcyZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2FkMGFiNTEyZmUwMDQ2Mjk4NTVmMTYwNGZjZGZhZWY0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFszNC4wMzEzLCAxMDguOTIzN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Y5ZWQ5ZDIzNzFiZTQxNzFiZTViMWFmMzI0ZDcyZTIyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBhMDYzYWQzYzU1YTQwN2U5ODRmYjczMGU3YzBlMTgwID0gJChgPGRpdiBpZD0iaHRtbF8wYTA2M2FkM2M1NWE0MDdlOTg0ZmI3MzBlN2MwZTE4MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+WEFOPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mOWVkOWQyMzcxYmU0MTcxYmU1YjFhZjMyNGQ3MmUyMi5zZXRDb250ZW50KGh0bWxfMGEwNjNhZDNjNTVhNDA3ZTk4NGZiNzMwZTdjMGUxODApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9hZDBhYjUxMmZlMDA0NjI5ODU1ZjE2MDRmY2RmYWVmNC5iaW5kUG9wdXAocG9wdXBfZjllZDlkMjM3MWJlNDE3MWJlNWIxYWYzMjRkNzJlMjIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zOWU2MDJlZmY4OTg0ZTEzYmVhMGE3NmM0ZTE4YWRhYyA9IEwubWFya2VyKAogICAgICAgICAgICBbNDIuNjM3NSwgNzQuNDk0Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdjYTI3Nzg2MTkxNzQzMzk5MDFiYmYzMzhlYjgwZDNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNiYjIyOWZmNGE5NzQ2ZGY4N2Q3OTAyNDk0MmUzNDdiID0gJChgPGRpdiBpZD0iaHRtbF8zYmIyMjlmZjRhOTc0NmRmODdkNzkwMjQ5NDJlMzQ3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUFLPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83Y2EyNzc4NjE5MTc0MzM5OTAxYmJmMzM4ZWI4MGQzZC5zZXRDb250ZW50KGh0bWxfM2JiMjI5ZmY0YTk3NDZkZjg3ZDc5MDI0OTQyZTM0N2IpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zOWU2MDJlZmY4OTg0ZTEzYmVhMGE3NmM0ZTE4YWRhYy5iaW5kUG9wdXAocG9wdXBfN2NhMjc3ODYxOTE3NDMzOTkwMWJiZjMzOGViODBkM2QpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kNDA0ZTllM2IwNDg0NDEwOThhZTkwYzMwMTg4MDkzOSA9IEwubWFya2VyKAogICAgICAgICAgICBbMzcuOTMwNCwgNTguMTE4OV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U1ZjBiNTkxYTZiMzRlODU4MDJjY2Y0N2E3ZTg0NjdlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2QzNzdjMzE4Y2E1ZjQwM2E4ZGFjMDQxOTNlOWQ0Y2EwID0gJChgPGRpdiBpZD0iaHRtbF9kMzc3YzMxOGNhNWY0MDNhOGRhYzA0MTkzZTlkNGNhMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUJLVDwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTVmMGI1OTFhNmIzNGU4NTgwMmNjZjQ3YTdlODQ2N2Uuc2V0Q29udGVudChodG1sX2QzNzdjMzE4Y2E1ZjQwM2E4ZGFjMDQxOTNlOWQ0Y2EwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZDQwNGU5ZTNiMDQ4NDQxMDk4YWU5MGMzMDE4ODA5MzkuYmluZFBvcHVwKHBvcHVwX2U1ZjBiNTkxYTZiMzRlODU4MDJjY2Y0N2E3ZTg0NjdlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmFkODM3OTljZWE5NGVkZTk4YmU0MjUwNzQzOWUzNTEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWy0xOS4wMTgsIDQ3LjIyOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I3MjlmYjBhM2FkOTQ5NTQ5ODIyYzljZTg1NDJkNTA3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcxZmIwMDJiZjM4NzQ4NWZhMzRmNjZjMzkyNzllMmIyID0gJChgPGRpdiBpZD0iaHRtbF83MWZiMDAyYmYzODc0ODVmYTM0ZjY2YzM5Mjc5ZTJiMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUJQTzwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjcyOWZiMGEzYWQ5NDk1NDk4MjJjOWNlODU0MmQ1MDcuc2V0Q29udGVudChodG1sXzcxZmIwMDJiZjM4NzQ4NWZhMzRmNjZjMzkyNzllMmIyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNmFkODM3OTljZWE5NGVkZTk4YmU0MjUwNzQzOWUzNTEuYmluZFBvcHVwKHBvcHVwX2I3MjlmYjBhM2FkOTQ5NTQ5ODIyYzljZTg1NDJkNTA3KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNzg3NmViYzI0NTJiNGQ5ZThhMTI5MGMwN2Q2Yjc2MTMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzgyLjUwMzMsIC02Mi4zNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzM4ZTU4ODFlNWY3YTQwNDNhN2JkMGNjZDM4ZGI4ZmZjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2FlZTViODU3YTgyMzQxMzFhNjBlMjBjM2IxZmZhZTQwID0gJChgPGRpdiBpZD0iaHRtbF9hZWU1Yjg1N2E4MjM0MTMxYTYwZTIwYzNiMWZmYWU0MCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUxFPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zOGU1ODgxZTVmN2E0MDQzYTdiZDBjY2QzOGRiOGZmYy5zZXRDb250ZW50KGh0bWxfYWVlNWI4NTdhODIzNDEzMWE2MGUyMGMzYjFmZmFlNDApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83ODc2ZWJjMjQ1MmI0ZDllOGExMjkwYzA3ZDZiNzYxMy5iaW5kUG9wdXAocG9wdXBfMzhlNTg4MWU1ZjdhNDA0M2E3YmQwY2NkMzhkYjhmZmMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kMGZjZDRlNzgzMzc0NmI5YTE1NTUzNDAxM2MzNWU2ZSA9IEwubWFya2VyKAogICAgICAgICAgICBbNTYuNDMwMiwgNTguNTYyNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMyNWM4MWFjZmMyMzQyOWI4NjhiOTI0ZmU5ZmRlZDg0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdhYTgzMzViMzc2NzQ5Yzk5NWJjZGE1MGM3ZjRjMjA0ID0gJChgPGRpdiBpZD0iaHRtbF83YWE4MzM1YjM3Njc0OWM5OTViY2RhNTBjN2Y0YzIwNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QVJVPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMjVjODFhY2ZjMjM0MjliODY4YjkyNGZlOWZkZWQ4NC5zZXRDb250ZW50KGh0bWxfN2FhODMzNWIzNzY3NDljOTk1YmNkYTUwYzdmNGMyMDQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9kMGZjZDRlNzgzMzc0NmI5YTE1NTUzNDAxM2MzNWU2ZS5iaW5kUG9wdXAocG9wdXBfMzI1YzgxYWNmYzIzNDI5Yjg2OGI5MjRmZTlmZGVkODQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iM2FlODE3ZmM2ODM0NDMwODAzYWM1NjkwYjA0MjRkMSA9IEwubWFya2VyKAogICAgICAgICAgICBbNTQuNzI1LCAtMTAxLjk3ODNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jOWQyZWRlYTU2MTI0ODFmYmI0MTYxY2M3NDZiMTE3MSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lMDA2NzI0M2Y1OGU0NzcwYTViOTQ3MTlkNGYyMGE2NyA9ICQoYDxkaXYgaWQ9Imh0bWxfZTAwNjcyNDNmNThlNDc3MGE1Yjk0NzE5ZDRmMjBhNjciIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkZGQzwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzlkMmVkZWE1NjEyNDgxZmJiNDE2MWNjNzQ2YjExNzEuc2V0Q29udGVudChodG1sX2UwMDY3MjQzZjU4ZTQ3NzBhNWI5NDcxOWQ0ZjIwYTY3KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYjNhZTgxN2ZjNjgzNDQzMDgwM2FjNTY5MGIwNDI0ZDEuYmluZFBvcHVwKHBvcHVwX2M5ZDJlZGVhNTYxMjQ4MWZiYjQxNjFjYzc0NmIxMTcxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmFjMzFhZWQyMmI4NDNiZTkzMzgzNzZkZjJhOWM5MzMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzEwLjI5MDgsIC04NC45NTI1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWFjYTFmZTgxNmZlNDZkZTkxYmRlMDFiMGIxYTkzMTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDZiYjhlYmJmODY2NDE2OGJkNzdmZGNlNzkyNDZlMjIgPSAkKGA8ZGl2IGlkPSJodG1sXzA2YmI4ZWJiZjg2NjQxNjhiZDc3ZmRjZTc5MjQ2ZTIyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5KVFM8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FhY2ExZmU4MTZmZTQ2ZGU5MWJkZTAxYjBiMWE5MzExLnNldENvbnRlbnQoaHRtbF8wNmJiOGViYmY4NjY0MTY4YmQ3N2ZkY2U3OTI0NmUyMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzZhYzMxYWVkMjJiODQzYmU5MzM4Mzc2ZGYyYTljOTMzLmJpbmRQb3B1cChwb3B1cF9hYWNhMWZlODE2ZmU0NmRlOTFiZGUwMWIwYjFhOTMxMSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzE1MTQ0ZjRlYTVkODRlNDdhZWNlMzg1MjM2Y2JiMmY3ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs1MC43MTU0LCA3OC42MjAyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTU0ZWQxOTgzZDI1NDgyODgyNDA4MmEzNjQzZjQwNTcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGI0MDM4ZTRjNDM1NDZlNzlkNzczOWJkYTk1YjNkYjcgPSAkKGA8ZGl2IGlkPSJodG1sXzRiNDAzOGU0YzQzNTQ2ZTc5ZDc3MzliZGE5NWIzZGI3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5LVVJLPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81NTRlZDE5ODNkMjU0ODI4ODI0MDgyYTM2NDNmNDA1Ny5zZXRDb250ZW50KGh0bWxfNGI0MDM4ZTRjNDM1NDZlNzlkNzczOWJkYTk1YjNkYjcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xNTE0NGY0ZWE1ZDg0ZTQ3YWVjZTM4NTIzNmNiYjJmNy5iaW5kUG9wdXAocG9wdXBfNTU0ZWQxOTgzZDI1NDgyODgyNDA4MmEzNjQzZjQwNTcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9lYjc2MGM1OWM2ODI0YzIzYjY5ZDFjMGUxNjU2YzM0ZCA9IEwubWFya2VyKAogICAgICAgICAgICBbLTQuNjczNywgNTUuNDc5Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk1NjIxN2M1MmIwOTQwYzc4YTEzNDY4ZjE4YzZkYTUzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzczY2EzNmE2ZjNiNDQ0ZWU4YmNhNDkyNTUzNmZlMzM0ID0gJChgPGRpdiBpZD0iaHRtbF83M2NhMzZhNmYzYjQ0NGVlOGJjYTQ5MjU1MzZmZTMzNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TVNFWTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTU2MjE3YzUyYjA5NDBjNzhhMTM0NjhmMThjNmRhNTMuc2V0Q29udGVudChodG1sXzczY2EzNmE2ZjNiNDQ0ZWU4YmNhNDkyNTUzNmZlMzM0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZWI3NjBjNTljNjgyNGMyM2I2OWQxYzBlMTY1NmMzNGQuYmluZFBvcHVwKHBvcHVwXzk1NjIxN2M1MmIwOTQwYzc4YTEzNDY4ZjE4YzZkYTUzKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMmQxZDc1ZWUxZjJiNGY4Mzg4MjQxYWViNTk4MjM5NDcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzUxLjY4MDcsIDEwMy42NDM4XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTQxYjc0NjE5OWVjNGViOWE5MmYwNTU5NjBmODFkNGQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDE5MGQ4OWJiNWYwNDQ1NjhmMGU4ZDFkOTI4MDJkYTUgPSAkKGA8ZGl2IGlkPSJodG1sXzQxOTBkODliYjVmMDQ0NTY4ZjBlOGQxZDkyODAyZGE1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5UTFk8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk0MWI3NDYxOTllYzRlYjlhOTJmMDU1OTYwZjgxZDRkLnNldENvbnRlbnQoaHRtbF80MTkwZDg5YmI1ZjA0NDU2OGYwZThkMWQ5MjgwMmRhNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzJkMWQ3NWVlMWYyYjRmODM4ODI0MWFlYjU5ODIzOTQ3LmJpbmRQb3B1cChwb3B1cF85NDFiNzQ2MTk5ZWM0ZWI5YTkyZjA1NTk2MGY4MWQ0ZCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzEwOTQzYzUxYjdjNTQ5MTliNzRlZmQzMTE1NWI5NDcwID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFszMi4zNzEzLCAtNjQuNjk2M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRlMDc3MWNiZGQ2NDRlYWJiNWI3ZDEyMzBkOTcwYjczID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzI5Y2FhZmZjYzcxZTQ3YzNiZTJjZjExMzc2MDI3NWViID0gJChgPGRpdiBpZD0iaHRtbF8yOWNhYWZmY2M3MWU0N2MzYmUyY2YxMTM3NjAyNzVlYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QkJTUjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNGUwNzcxY2JkZDY0NGVhYmI1YjdkMTIzMGQ5NzBiNzMuc2V0Q29udGVudChodG1sXzI5Y2FhZmZjYzcxZTQ3YzNiZTJjZjExMzc2MDI3NWViKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMTA5NDNjNTFiN2M1NDkxOWI3NGVmZDMxMTU1Yjk0NzAuYmluZFBvcHVwKHBvcHVwXzRlMDc3MWNiZGQ2NDRlYWJiNWI3ZDEyMzBkOTcwYjczKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNGFmNDFjOWI2MDNlNDU1Mjk5MDA0NTI2ZWFjOTBjMzkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE4LjgxNDEsIDk4Ljk0NDNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MTBiNzAyNTdkNGQ0MzkxOTRkNDA5Y2E1ZDdiYzk2YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8wOTg1YjlmZGI3YjE0ZDY4YjJkMjhiNmRjNTAxMzhlNSA9ICQoYDxkaXYgaWQ9Imh0bWxfMDk4NWI5ZmRiN2IxNGQ2OGIyZDI4YjZkYzUwMTM4ZTUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkNIVE88L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzUxMGI3MDI1N2Q0ZDQzOTE5NGQ0MDljYTVkN2JjOTZiLnNldENvbnRlbnQoaHRtbF8wOTg1YjlmZGI3YjE0ZDY4YjJkMjhiNmRjNTAxMzhlNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzRhZjQxYzliNjAzZTQ1NTI5OTAwNDUyNmVhYzkwYzM5LmJpbmRQb3B1cChwb3B1cF81MTBiNzAyNTdkNGQ0MzkxOTRkNDA5Y2E1ZDdiYzk2YikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzIyYTFiM2I4MDQ2YTQxMmM5OGNmY2EzMGEzNGY0NmRjID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0NC41ODU1LCAtMTIzLjMwNDZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83YTU1MjA0YzU1ZjM0YTRkYjE3ZmE3NTg0NmIyN2E1YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82NmFkYjcxM2EzNzA0NDI2ODdiZjdmODdkN2U1ZTI1NiA9ICQoYDxkaXYgaWQ9Imh0bWxfNjZhZGI3MTNhMzcwNDQyNjg3YmY3Zjg3ZDdlNWUyNTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkNPUjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfN2E1NTIwNGM1NWYzNGE0ZGIxN2ZhNzU4NDZiMjdhNWIuc2V0Q29udGVudChodG1sXzY2YWRiNzEzYTM3MDQ0MjY4N2JmN2Y4N2Q3ZTVlMjU2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMjJhMWIzYjgwNDZhNDEyYzk4Y2ZjYTMwYTM0ZjQ2ZGMuYmluZFBvcHVwKHBvcHVwXzdhNTUyMDRjNTVmMzRhNGRiMTdmYTc1ODQ2YjI3YTViKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMzc3ZmIwOTgyNGQzNDQzYjhiNTFjMjdjYjhiMGQxOTggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExMDMsIC04MS40MzI3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOGZmNTMyYTg4NmJhNDk1Mzg5NTcyMjcwYTBkNDFmZWUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDgzZjBiZTY0NTU4NGEzOGJhNzY4MDg1YTMxZTI1OWIgPSAkKGA8ZGl2IGlkPSJodG1sXzQ4M2YwYmU2NDU1ODRhMzhiYTc2ODA4NWEzMWUyNTliIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5EV1BGPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84ZmY1MzJhODg2YmE0OTUzODk1NzIyNzBhMGQ0MWZlZS5zZXRDb250ZW50KGh0bWxfNDgzZjBiZTY0NTU4NGEzOGJhNzY4MDg1YTMxZTI1OWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zNzdmYjA5ODI0ZDM0NDNiOGI1MWMyN2NiOGIwZDE5OC5iaW5kUG9wdXAocG9wdXBfOGZmNTMyYTg4NmJhNDk1Mzg5NTcyMjcwYTBkNDFmZWUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl84NjZkNGI1NjljOTM0ODJhODQ0N2UwNDQwZjk1YzRkOSA9IEwubWFya2VyKAogICAgICAgICAgICBbMzcuNDc3NiwgMTI2LjYyMzldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYzY2Zjg0M2QyNzc0YjhlYjZjNzNhYmEyMzFiYTA5MyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mZjg3OGYzNjMwMGE0OWZlOWZiMzlkOWFiODU3ZDhlMCA9ICQoYDxkaXYgaWQ9Imh0bWxfZmY4NzhmMzYzMDBhNDlmZTlmYjM5ZDlhYjg1N2Q4ZTAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPklOQ048L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RjNjZmODQzZDI3NzRiOGViNmM3M2FiYTIzMWJhMDkzLnNldENvbnRlbnQoaHRtbF9mZjg3OGYzNjMwMGE0OWZlOWZiMzlkOWFiODU3ZDhlMCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzg2NmQ0YjU2OWM5MzQ4MmE4NDQ3ZTA0NDBmOTVjNGQ5LmJpbmRQb3B1cChwb3B1cF9kYzY2Zjg0M2QyNzc0YjhlYjZjNzNhYmEyMzFiYTA5MykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzg5MmYwNzIzMTU3ZDQxYTViMGViYTNjZDZlZDQ0MzNhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFszNC41NDA4LCA2OS4wNDMyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWViZDkzMGVlNDc4NDZkOWI1MTI4YzJlNWZjMmI0MzUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODE2MDQ2MjllMjE3NDQ2YmI5YTA1MThmZmE3ZWY5NDUgPSAkKGA8ZGl2IGlkPSJodG1sXzgxNjA0NjI5ZTIxNzQ0NmJiOWEwNTE4ZmZhN2VmOTQ1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5LQkw8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FlYmQ5MzBlZTQ3ODQ2ZDliNTEyOGMyZTVmYzJiNDM1LnNldENvbnRlbnQoaHRtbF84MTYwNDYyOWUyMTc0NDZiYjlhMDUxOGZmYTdlZjk0NSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzg5MmYwNzIzMTU3ZDQxYTViMGViYTNjZDZlZDQ0MzNhLmJpbmRQb3B1cChwb3B1cF9hZWJkOTMwZWU0Nzg0NmQ5YjUxMjhjMmU1ZmMyYjQzNSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzFmMmNhNmYyNmRlMDQ5MDQ5ZWNhNWRmNTAzZDc0NGIzID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstMTUuMjc3OSwgMjguMTg4Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RkZTljOWQ5OTExMzQxNGI5YmE1N2QxOWNkYmM3MTAzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzlmMGQ1NjhmYzc4MzQ4OTdhNTc1NTExZDJmODkxN2EwID0gJChgPGRpdiBpZD0iaHRtbF85ZjBkNTY4ZmM3ODM0ODk3YTU3NTUxMWQyZjg5MTdhMCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TFNaPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kZGU5YzlkOTkxMTM0MTRiOWJhNTdkMTljZGJjNzEwMy5zZXRDb250ZW50KGh0bWxfOWYwZDU2OGZjNzgzNDg5N2E1NzU1MTFkMmY4OTE3YTApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xZjJjYTZmMjZkZTA0OTA0OWVjYTVkZjUwM2Q3NDRiMy5iaW5kUG9wdXAocG9wdXBfZGRlOWM5ZDk5MTEzNDE0YjliYTU3ZDE5Y2RiYzcxMDMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80NjZlYzc4YWE1YWE0ZjczYTlhMTI0MGRjZGUxNTI2OCA9IEwubWFya2VyKAogICAgICAgICAgICBbMC4yMzc2LCAtNzguNDUwOF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzBhMDhmODRjZWI4MzRjMzdiNDBlZTg5YjA0MDIzMmQ5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzIyMWE0YjUzMWMzMDQ4YTU5NmZlODZlZjZkYzg0ODYxID0gJChgPGRpdiBpZD0iaHRtbF8yMjFhNGI1MzFjMzA0OGE1OTZmZTg2ZWY2ZGM4NDg2MSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+T1RBVjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGEwOGY4NGNlYjgzNGMzN2I0MGVlODliMDQwMjMyZDkuc2V0Q29udGVudChodG1sXzIyMWE0YjUzMWMzMDQ4YTU5NmZlODZlZjZkYzg0ODYxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNDY2ZWM3OGFhNWFhNGY3M2E5YTEyNDBkY2RlMTUyNjguYmluZFBvcHVwKHBvcHVwXzBhMDhmODRjZWI4MzRjMzdiNDBlZTg5YjA0MDIzMmQ5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTQ2ZjU2ZGMxM2Q3NDljODgzMGE2NTE5NWNlYjZmMTUgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzUzLjAyMzMsIDE1OC42NDk5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZDAyNmIzMDA2MDY2NGJiM2ExMGU4NjYzODcyMjhlNjggPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTZlMGRmZTY2ZTJkNDRjZDgzMTAzMWU1NDkxMjRiNGMgPSAkKGA8ZGl2IGlkPSJodG1sXzU2ZTBkZmU2NmUyZDQ0Y2Q4MzEwMzFlNTQ5MTI0YjRjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5QRVQ8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2QwMjZiMzAwNjA2NjRiYjNhMTBlODY2Mzg3MjI4ZTY4LnNldENvbnRlbnQoaHRtbF81NmUwZGZlNjZlMmQ0NGNkODMxMDMxZTU0OTEyNGI0Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzE0NmY1NmRjMTNkNzQ5Yzg4MzBhNjUxOTVjZWI2ZjE1LmJpbmRQb3B1cChwb3B1cF9kMDI2YjMwMDYwNjY0YmIzYTEwZTg2NjM4NzIyOGU2OCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzNiNWY4NjM3ZGE3YzQ3NDY4YzhiNzFlMmRjMzNlOWE5ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstNS44Mjc0LCAtMzUuOTAxNF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc1OTBhZWIwN2EyNzQzNDQ5OTFmODViZmMwMmQwODNhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQzMjMwZTM2MWMzNzRkMzNhNzcxYzY3NmY4MDZiMzQ5ID0gJChgPGRpdiBpZD0iaHRtbF80MzIzMGUzNjFjMzc0ZDMzYTc3MWM2NzZmODA2YjM0OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+UkNCUjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzU5MGFlYjA3YTI3NDM0NDk5MWY4NWJmYzAyZDA4M2Euc2V0Q29udGVudChodG1sXzQzMjMwZTM2MWMzNzRkMzNhNzcxYzY3NmY4MDZiMzQ5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfM2I1Zjg2MzdkYTdjNDc0NjhjOGI3MWUyZGMzM2U5YTkuYmluZFBvcHVwKHBvcHVwXzc1OTBhZWIwN2EyNzQzNDQ5OTFmODViZmMwMmQwODNhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMzZlMWYzMWYxZjQ5NDI3NjkwNDM4YTEwOTU0OWM3NjggPSBMLm1hcmtlcigKICAgICAgICAgICAgWy04Ljk0ODksIC02My4xODMxXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMGIxZjZiODE3NjE0NGZkNWExNTFmZjM4ZmYyNzQyMjEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmQ5MDdlMDIzZTZkNDVmMjg5NjQzOTYzZjhlODU5MjMgPSAkKGA8ZGl2IGlkPSJodG1sX2ZkOTA3ZTAyM2U2ZDQ1ZjI4OTY0Mzk2M2Y4ZTg1OTIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TQU1MPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wYjFmNmI4MTc2MTQ0ZmQ1YTE1MWZmMzhmZjI3NDIyMS5zZXRDb250ZW50KGh0bWxfZmQ5MDdlMDIzZTZkNDVmMjg5NjQzOTYzZjhlODU5MjMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zNmUxZjMxZjFmNDk0Mjc2OTA0MzhhMTA5NTQ5Yzc2OC5iaW5kUG9wdXAocG9wdXBfMGIxZjZiODE3NjE0NGZkNWExNTFmZjM4ZmYyNzQyMjEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yZGVhMDViM2I3NjQ0OWY1ODVmMzUyYzNkMzI1YjI2MiA9IEwubWFya2VyKAogICAgICAgICAgICBbOC44ODM5LCAtNzAuNjM0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzVhOTNkZThjZmViNDU0NjllNDkzYzdlMTlkMTNiMDEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjdlZGFmM2U2NWQ4NGRmZWJiNGI2YzdlNzU3YzNmZGUgPSAkKGA8ZGl2IGlkPSJodG1sX2Y3ZWRhZjNlNjVkODRkZmViYjRiNmM3ZTc1N2MzZmRlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TRFY8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc1YTkzZGU4Y2ZlYjQ1NDY5ZTQ5M2M3ZTE5ZDEzYjAxLnNldENvbnRlbnQoaHRtbF9mN2VkYWYzZTY1ZDg0ZGZlYmI0YjZjN2U3NTdjM2ZkZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzJkZWEwNWIzYjc2NDQ5ZjU4NWYzNTJjM2QzMjViMjYyLmJpbmRQb3B1cChwb3B1cF83NWE5M2RlOGNmZWI0NTQ2OWU0OTNjN2UxOWQxM2IwMSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzdlMzE1NzZiZWI0OTRmMjE5NGE3OGNmMGJlOGExYTVlID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs2Ni45OTYxLCAtNTAuNjIwNzZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNWNiNmUyMzdhNmU0N2Q0YjcxOTFhY2VmNWE3NmM2YyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85YzVlNzk5ZmYyYzQ0MTdjODc2ZmM3MWE4M2YzN2Y5OSA9ICQoYDxkaXYgaWQ9Imh0bWxfOWM1ZTc5OWZmMmM0NDE3Yzg3NmZjNzFhODNmMzdmOTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlNGSkQ8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2I1Y2I2ZTIzN2E2ZTQ3ZDRiNzE5MWFjZWY1YTc2YzZjLnNldENvbnRlbnQoaHRtbF85YzVlNzk5ZmYyYzQ0MTdjODc2ZmM3MWE4M2YzN2Y5OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzdlMzE1NzZiZWI0OTRmMjE5NGE3OGNmMGJlOGExYTVlLmJpbmRQb3B1cChwb3B1cF9iNWNiNmUyMzdhNmU0N2Q0YjcxOTFhY2VmNWE3NmM2YykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzYyMTljZTIwODU4OTQ5ZmQ4YzJhZGJkOGFiZWM3NTRmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0MC42MzU4LCAtNzcuODg3Nl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2U1NGRkYWY2NTFhMjRjOGZiMDMyZTdmNzEzYjA0MDU2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNiYzM5NTY2MzJiOTQwODNhYjkzZGRlZTM3ZjA1YWI1ID0gJChgPGRpdiBpZD0iaHRtbF8zYmMzOTU2NjMyYjk0MDgzYWI5M2RkZWUzN2YwNWFiNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+U1NQQTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTU0ZGRhZjY1MWEyNGM4ZmIwMzJlN2Y3MTNiMDQwNTYuc2V0Q29udGVudChodG1sXzNiYzM5NTY2MzJiOTQwODNhYjkzZGRlZTM3ZjA1YWI1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNjIxOWNlMjA4NTg5NDlmZDhjMmFkYmQ4YWJlYzc1NGYuYmluZFBvcHVwKHBvcHVwX2U1NGRkYWY2NTFhMjRjOGZiMDMyZTdmNzEzYjA0MDU2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTc4YzY4NGRkZjUwNGNlYmE3MjIyMjI5NjQ3MmU5NzEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzIwLjIyNjMsIC04OC4yNzYzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfODk1OTU0ZWI3YThmNDIzYjliNWQ1MjA5MGNlNjFiOGIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZWRiNDZlOWY3ZTk2NGY0MDg2ZDEzMjZjYzRmNTY5ZGUgPSAkKGA8ZGl2IGlkPSJodG1sX2VkYjQ2ZTlmN2U5NjRmNDA4NmQxMzI2Y2M0ZjU2OWRlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5URUlHPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84OTU5NTRlYjdhOGY0MjNiOWI1ZDUyMDkwY2U2MWI4Yi5zZXRDb250ZW50KGh0bWxfZWRiNDZlOWY3ZTk2NGY0MDg2ZDEzMjZjYzRmNTY5ZGUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8xNzhjNjg0ZGRmNTA0Y2ViYTcyMjIyMjk2NDcyZTk3MS5iaW5kUG9wdXAocG9wdXBfODk1OTU0ZWI3YThmNDIzYjliNWQ1MjA5MGNlNjFiOGIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85YjIxZDQ5MWQ2MWM0ZDc2OTQyZTJkYmVmMjc3MDdkMyA9IEwubWFya2VyKAogICAgICAgICAgICBbLTE5LjIwMjIsIDE3LjU4MzhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF85NDY3MTJkOGVkNDA0YWE4OTkyOWRlZGMzMDAwMDg5ZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mYTUzM2JlZDdjYWQ0OGFiYWVmZTVlNzg0ZjJkZTRhZiA9ICQoYDxkaXYgaWQ9Imh0bWxfZmE1MzNiZWQ3Y2FkNDhhYmFlZmU1ZTc4NGYyZGU0YWYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlRTVU08L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk0NjcxMmQ4ZWQ0MDRhYTg5OTI5ZGVkYzMwMDAwODllLnNldENvbnRlbnQoaHRtbF9mYTUzM2JlZDdjYWQ0OGFiYWVmZTVlNzg0ZjJkZTRhZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzliMjFkNDkxZDYxYzRkNzY5NDJlMmRiZWYyNzcwN2QzLmJpbmRQb3B1cChwb3B1cF85NDY3MTJkOGVkNDA0YWE4OTkyOWRlZGMzMDAwMDg5ZSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzMzOTliZjJiNDk2ZTRhZDQ5MTA4Njg5ZGMyZTQzNzc2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0Ny44NjUxLCAxMDcuMDUzMl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRiZjdiYzZlZWU1YjQ3OTc4ZGQxNDdjYTkyYzBmMmM1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhhZWExMWQzNjBiZTRlNmM4MWVkZGZhODNkMmY5OGZjID0gJChgPGRpdiBpZD0iaHRtbF84YWVhMTFkMzYwYmU0ZTZjODFlZGRmYTgzZDJmOThmYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+VUxOPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80YmY3YmM2ZWVlNWI0Nzk3OGRkMTQ3Y2E5MmMwZjJjNS5zZXRDb250ZW50KGh0bWxfOGFlYTExZDM2MGJlNGU2YzgxZWRkZmE4M2QyZjk4ZmMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zMzk5YmYyYjQ5NmU0YWQ0OTEwODY4OWRjMmU0Mzc3Ni5iaW5kUG9wdXAocG9wdXBfNGJmN2JjNmVlZTViNDc5NzhkZDE0N2NhOTJjMGYyYzUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80OTA0NjBhNGFiYzE0YmE3YjRlMDI3NDYwNjg5YjgzYSA9IEwubWFya2VyKAogICAgICAgICAgICBbMzguMjI4OSwgLTg2LjI5MzldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kMGI2MzM0NDE2YzU0MzcwYjVlZTI4MjlkOGViZTAyNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83Mjc3NDg4OWQ5NmQ0ZDhlYTFlYWE4NDdjNDgxYzFkMSA9ICQoYDxkaXYgaWQ9Imh0bWxfNzI3NzQ4ODlkOTZkNGQ4ZWExZWFhODQ3YzQ4MWMxZDEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPldDSTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDBiNjMzNDQxNmM1NDM3MGI1ZWUyODI5ZDhlYmUwMjcuc2V0Q29udGVudChodG1sXzcyNzc0ODg5ZDk2ZDRkOGVhMWVhYTg0N2M0ODFjMWQxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNDkwNDYwYTRhYmMxNGJhN2I0ZTAyNzQ2MDY4OWI4M2EuYmluZFBvcHVwKHBvcHVwX2QwYjYzMzQ0MTZjNTQzNzBiNWVlMjgyOWQ4ZWJlMDI3KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMmQwNGVmOTYzNjcxNGUxYTg4NzkyMWRlMjlmZmQ0NzcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzYyLjAzMSwgMTI5LjY4MDVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83NTg2YzRkZDAzMTI0YzIzYmVlMmViZWZhMjM1ODU1NiA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF83OGZlYTZiMmUzYjQ0MTg1ODVhYWU2OWU4MGViZGY3ZiA9ICQoYDxkaXYgaWQ9Imh0bWxfNzhmZWE2YjJlM2I0NDE4NTg1YWFlNjllODBlYmRmN2YiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPllBSzwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNzU4NmM0ZGQwMzEyNGMyM2JlZTJlYmVmYTIzNTg1NTYuc2V0Q29udGVudChodG1sXzc4ZmVhNmIyZTNiNDQxODU4NWFhZTY5ZTgwZWJkZjdmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMmQwNGVmOTYzNjcxNGUxYTg4NzkyMWRlMjlmZmQ0NzcuYmluZFBvcHVwKHBvcHVwXzc1ODZjNGRkMDMxMjRjMjNiZWUyZWJlZmEyMzU4NTU2KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMjNkMjIzMzNkM2FiNDA1Njk4OWRkNDYwMDNjYTNhOTkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzQ0LjExODgsIDE0Mi41OTNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80OWI1NTE4NjU0ZTg0ZjI5YjU3NjQ0YzNkZGNkYjQyYyA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8xZjVmNjMxYzI2Yzg0MDVjODBjZDQ4NWMxMzI1YjVjYSA9ICQoYDxkaXYgaWQ9Imh0bWxfMWY1ZjYzMWMyNmM4NDA1YzgwY2Q0ODVjMTMyNWI1Y2EiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkFTQUo8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ5YjU1MTg2NTRlODRmMjliNTc2NDRjM2RkY2RiNDJjLnNldENvbnRlbnQoaHRtbF8xZjVmNjMxYzI2Yzg0MDVjODBjZDQ4NWMxMzI1YjVjYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzIzZDIyMzMzZDNhYjQwNTY5ODlkZDQ2MDAzY2EzYTk5LmJpbmRQb3B1cChwb3B1cF80OWI1NTE4NjU0ZTg0ZjI5YjU3NjQ0YzNkZGNkYjQyYykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2FiMDZjMGE1MGI0YTQ4YjFhZTRhZTQ1ZDc2ZjJmYTZhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs1MC40MzQ4LCA1OC4wMTY0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCksCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1KTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTM5NWVlNDhkZGZlNDQ2NGIzZDJhYTMyN2I0NDliZTkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzEwMCUnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMDBjYzEzOTc3OWY5NDY2MGI4OGQ4ZDMwOWYwMjM4OTcgPSAkKGA8ZGl2IGlkPSJodG1sXzAwY2MxMzk3NzlmOTQ2NjBiODhkOGQzMDlmMDIzODk3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5BS1RPPC9iPjwvaDQ+PC9kaXY+YClbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xMzk1ZWU0OGRkZmU0NDY0YjNkMmFhMzI3YjQ0OWJlOS5zZXRDb250ZW50KGh0bWxfMDBjYzEzOTc3OWY5NDY2MGI4OGQ4ZDMwOWYwMjM4OTcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9hYjA2YzBhNTBiNGE0OGIxYWU0YWU0NWQ3NmYyZmE2YS5iaW5kUG9wdXAocG9wdXBfMTM5NWVlNDhkZGZlNDQ2NGIzZDJhYTMyN2I0NDliZTkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl83MDI5ODhhNjhhYjc0ZWQ5YWQwNmJmMTA1MDBlOWMyOSA9IEwubWFya2VyKAogICAgICAgICAgICBbMS4zNjA4LCAxMDMuNzcyOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZkMTU1NWY4MDZiODQ2ZWFhMzE5MWQ5MjNkMjQwNGI4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMyZTQ4NjUzZDQ2ZjQ4NWFiNDVkNjBjMTY2MjU1NDhmID0gJChgPGRpdiBpZD0iaHRtbF8zMmU0ODY1M2Q0NmY0ODVhYjQ1ZDYwYzE2NjI1NTQ4ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QlRERjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNmQxNTU1ZjgwNmI4NDZlYWEzMTkxZDkyM2QyNDA0Yjguc2V0Q29udGVudChodG1sXzMyZTQ4NjUzZDQ2ZjQ4NWFiNDVkNjBjMTY2MjU1NDhmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNzAyOTg4YTY4YWI3NGVkOWFkMDZiZjEwNTAwZTljMjkuYmluZFBvcHVwKHBvcHVwXzZkMTU1NWY4MDZiODQ2ZWFhMzE5MWQ5MjNkMjQwNGI4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZTZjZWQ2MjlmNDU3NDg4NzgwODA4ZTViNzNmZTYwYWQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzcwLjk4NjYsIC04LjUwNTddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKSwKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfNTA2NzQ1OTJjNzVlNGZhYzk2ZDAxMDNjNGNiNGYyOTUpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80YzQ1ZjQwMzc4YzM0NDlhYTE2NDAxNTkxMTQ3MTg1NSA9IEwucG9wdXAoe21heFdpZHRoOiAnMTAwJScKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hNjYyNGY5ZTRiZGU0NzQzYjU2YTg3ZWM2YmY1NGRiZiA9ICQoYDxkaXYgaWQ9Imh0bWxfYTY2MjRmOWU0YmRlNDc0M2I1NmE4N2VjNmJmNTRkYmYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkpNSUM8L2I+PC9oND48L2Rpdj5gKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRjNDVmNDAzNzhjMzQ0OWFhMTY0MDE1OTExNDcxODU1LnNldENvbnRlbnQoaHRtbF9hNjYyNGY5ZTRiZGU0NzQzYjU2YTg3ZWM2YmY1NGRiZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2U2Y2VkNjI5ZjQ1NzQ4ODc4MDgwOGU1YjczZmU2MGFkLmJpbmRQb3B1cChwb3B1cF80YzQ1ZjQwMzc4YzM0NDlhYTE2NDAxNTkxMTQ3MTg1NSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2ZiMGUzOGM3Mjg0OTQ2ODM4N2YwMmZhNjUzZmNhNTg2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0Ny45NDYyLCAtOTEuNDk1M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzk0YTEyMTA4Y2Y0MjRiMDI4NjA1NTEzNGIwNDA0ZDE3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzlhMzhmOThhMWQ0MTQxOWI5MGVkNjRmOTFiMjI3MWE1ID0gJChgPGRpdiBpZD0iaHRtbF85YTM4Zjk4YTFkNDE0MTliOTBlZDY0ZjkxYjIyNzFhNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+RVlNTjwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOTRhMTIxMDhjZjQyNGIwMjg2MDU1MTM0YjA0MDRkMTcuc2V0Q29udGVudChodG1sXzlhMzhmOThhMWQ0MTQxOWI5MGVkNjRmOTFiMjI3MWE1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZmIwZTM4YzcyODQ5NDY4Mzg3ZjAyZmE2NTNmY2E1ODYuYmluZFBvcHVwKHBvcHVwXzk0YTEyMTA4Y2Y0MjRiMDI4NjA1NTEzNGIwNDA0ZDE3KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfODdiYzg0ZGE1MGMxNGE1YThmNzgwYzE1NWQ0M2ViOTEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE0LjQ4NzI0LCA0OS4wMzc3OV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzI1MTc1MjMwODkyZTRiZmNiOTUxZWI1ZDAxY2I0MDNkID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzYyZWM5NTMwNTI0MjQ3YmY5MDE3ZTQ4ZmE3MGNiODZmID0gJChgPGRpdiBpZD0iaHRtbF82MmVjOTUzMDUyNDI0N2JmOTAxN2U0OGZhNzBjYjg2ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TVVLQTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjUxNzUyMzA4OTJlNGJmY2I5NTFlYjVkMDFjYjQwM2Quc2V0Q29udGVudChodG1sXzYyZWM5NTMwNTI0MjQ3YmY5MDE3ZTQ4ZmE3MGNiODZmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODdiYzg0ZGE1MGMxNGE1YThmNzgwYzE1NWQ0M2ViOTEuYmluZFBvcHVwKHBvcHVwXzI1MTc1MjMwODkyZTRiZmNiOTUxZWI1ZDAxY2I0MDNkKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNWY5YWMzODJkYTViNDI3Mjg0OGEwMTBkOGMzNWIyZTIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzEzLjYzNSwgMzguOTgxMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpLAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RiNjZiNzU3Njc1MzQ2M2NhOGExMzY1ZWFiYWM4NGRmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICcxMDAlJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzk5MWIyMjJhMGRkNTQxYzU5MmE3ZGJiZDA4ZWRmMTdmID0gJChgPGRpdiBpZD0iaHRtbF85OTFiMjIyYTBkZDU0MWM1OTJhN2RiYmQwOGVkZjE3ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QURZRTwvYj48L2g0PjwvZGl2PmApWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZGI2NmI3NTc2NzUzNDYzY2E4YTEzNjVlYWJhYzg0ZGYuc2V0Q29udGVudChodG1sXzk5MWIyMjJhMGRkNTQxYzU5MmE3ZGJiZDA4ZWRmMTdmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNWY5YWMzODJkYTViNDI3Mjg0OGEwMTBkOGMzNWIyZTIuYmluZFBvcHVwKHBvcHVwX2RiNjZiNzU3Njc1MzQ2M2NhOGExMzY1ZWFiYWM4NGRmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICAgICAgdmFyIGxhdF9sbmdfcG9wdXBfOGU2MzVmOGJmOGRjNDExMmJkYjgzNDIxMzM3YTdiZmIgPSBMLnBvcHVwKCk7CiAgICAgICAgICAgICAgICBmdW5jdGlvbiBsYXRMbmdQb3AoZSkgewogICAgICAgICAgICAgICAgICAgIGxhdF9sbmdfcG9wdXBfOGU2MzVmOGJmOGRjNDExMmJkYjgzNDIxMzM3YTdiZmIKICAgICAgICAgICAgICAgICAgICAgICAgLnNldExhdExuZyhlLmxhdGxuZykKICAgICAgICAgICAgICAgICAgICAgICAgLnNldENvbnRlbnQoIkxhdGl0dWRlOiAiICsgZS5sYXRsbmcubGF0LnRvRml4ZWQoNCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkxvbmdpdHVkZTogIiArIGUubGF0bG5nLmxuZy50b0ZpeGVkKDQpKQogICAgICAgICAgICAgICAgICAgICAgICAub3Blbk9uKG1hcF81MDY3NDU5MmM3NWU0ZmFjOTZkMDEwM2M0Y2I0ZjI5NSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgbWFwXzUwNjc0NTkyYzc1ZTRmYWM5NmQwMTAzYzRjYjRmMjk1Lm9uKCdjbGljaycsIGxhdExuZ1BvcCk7CiAgICAgICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
|
|
],
|
|
"text/plain": [
|
|
"<folium.folium.Map at 0x7f1bacc27fd0>"
|
|
]
|
|
},
|
|
"execution_count": 19,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def plot_stations():\n",
|
|
" import folium\n",
|
|
" fmap = folium.Map(\n",
|
|
" location=[best_source.lat, best_source.lon],\n",
|
|
" tiles='Stamen Terrain',\n",
|
|
" zoom_start=3)\n",
|
|
" folium.Marker([best_source.lat, best_source.lon],\n",
|
|
" popup=('2009 Aquila Earthquake'),\n",
|
|
" icon=folium.Icon(color='red', icon='info-sign')).add_to(fmap)\n",
|
|
" \n",
|
|
" for s in stations_list:\n",
|
|
" folium.Marker([s.lat, s.lon],\n",
|
|
" popup='<b>%s</b></h4>' % s.station).add_to(fmap)\n",
|
|
" fmap.add_child(folium.LatLngPopup())\n",
|
|
" return fmap\n",
|
|
" \n",
|
|
"plot_stations()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAaMAAAEjCAYAAACfJW4sAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzsnXd8VeX5wL/PvTd7J5CEQELYS4aAiAiConXvQbWlUn+tWlut1mpta61aq621jtZaR+use++NE0GGIIiyd0JC9p73Pr8/nhO8RkbAhAR4v5/P/eTec97znvc9Ofc8932mqCoOh8PhcHQmvs4egMPhcDgcThg5HA6Ho9NxwsjhcDgcnY4TRg6Hw+HodJwwcjgcDken44SRw+FwODodJ4wcbUJEDhWRlSJSLSKndML5B4nIQhGpEpFLRORuEflDO/X9MxEp9OaW1h59tgciMkVENnX2ONoLEckVERWRQGePxdH1cMKoCyMivxWR11ptW7mdbd/v4OFcD9ypqvGq+kIHn2tbXAm8r6oJqvoPVb1QVf8E3+2hLSIRwK3A97y5lXzXgYrIOhGp84RboYg8ICLx22k7Q0SCXttKEVkkIid81zE49i68e+bIHex/3btHwl/1nnDP2ZNj7SicMOrafAgcKiJ+ABHJBCKA0a229ffadiS9gaW7c2A7/RLe7fPvhAwgenf6FmN736ETVTUeGA0cBFy9g65me22Tgf8CT4lI6q6Ox7HvoqrHej+W4r17JQmYAzysqhs6eXjtghNGXZt5mPAZ5X0+DHgPWN5q22pVzQcQkTtEZKP3K3uBiEzytmd5v9a3PuRE5EARKfZWB4jIeSLylYiUicibItLb274a6Au87P0ii/L6e0lESkVklYj8NKzfa0XkGRH5n4hUAjO8bU9726pEZImIDPRWf1u8MX9vWxdBRGYChwN3eucfKCIPisgNIhIHvA5khf1izBKRcSIy37sOhSJy6zb6HehdS4By7zyIyAQRmSciFd7fCWHHvC8ifxaRWUCtd122i6rmeeM7YEftvLYh4H4gJrxfEbncu0abReTHYduP91SXld71uzZsX7R3rUtEpNybR4a3L0lE/uv1l+ddR/+2xuRdx9leH5tF5E4RiQzbryJyodjqvExE/iUi4u3zi8gt3j22Bjh+R/MXkWwReU5Eirxx3+lt94nI1SKy3rsOD4tIkrevRfX3Y+8alHnjOUhEFnvjvjPsHDNEZJaI/NP7/y4Tkalh+3d2Xz/lnb9KRJaKyNhWxz7rjX+tiFzSlmNF5BEgh6+/X1fu6Dp53AikAj9rQ9u9A1V1ry78woTPZd77O4HzgD+32nZ/WPsfAmlAALgcKACivX0zgZ+Gtf0bcLf3/hRgFTDEO/Zq4JOwtuuAI8M+fwDcha0qRgFFwFRv37VAk9enD3u4XgvUA0d7/T8MrAV+jwncnwJrd3Ad3gd+Evb5QeAG7/0UYFOr9rOB6d77eGD8dvrNBRQIeJ9TgTJgujfOs73PaWHj2AAM8/ZHbKPPrdcKyMZWXX/azvlnAB977wPAL4Eq7JfvFKAZU5FGAMdhAjAlbN7DvWs8AigETvH2XQC8DMQCfmAMkOjtewG4B4gD0oG5wAXbGd8YYLw3tlzgK+DSsP0KvIKt6nK8++AYb9+FwDLvGqRi9/LWa93qPH7gc+A2b1zRwERv33nYvdnX+18+BzzS6v93t3fM97D77AVvbj2BLcDksOvdDFzmXdNpQAWQ2sb7ut77P/iBm4A53j4fsAC4Boj0xroGOHpnx27r+7WTZ8LJQDkwoLOfT+356vQBuNdO/kF2Ez/vvf8cGAAc02rbuTs4vgwY6b3/CTDTey/ARuAw7/PrwP+FHefDHny9vc9bvyzewyUIJIS1vwl4MGzMH25jHm+HfT4RqAb83ucE76GSvJ15vM+uCaMPgeuAbju5vrl8UxhNB+a2ajMbmBE2jut30uc6b27lwHrs4RaznbYzsIdjOVCMqV6ODJtXHWEPb+zBuj3Bejtwm/f+POATYESrNhlAQ/h4MIH7Xhvvx0tb7j3vs+IJDe/zU8BV3vuZwIVh+77H9oXRIdiDf1v73gUuCvs8CPux0yIgFegZtr8EmBb2+Vk8Aepd73xAwvbP9f7vbbmv3wnbNxSo894fDGxoNe7fAg/s7NjW36+dXP9+2Hf69Lb8v/aml1PTdX0+BCaKSArQXVVXYg+ZCd62AwizF3kqna88FUQ59gu7m7f7GeAQEcnC1HsKfOTt6w3c4ak1yoFSTGD13MaYsoBSVa0K27a+VduN2ziuMOx9HVCsqsGwz2C/fNuD/wMGAss8FVVbnQKysLmE05a5teYUVU1W1d6qepGq1onIpDBVYriNao7XtpuqjlfVd8L2lahqc9jnWrxrJCIHi8h7nlqoAluJtPyvHwHeBJ4QkXwRuVlMHdsbWxFsDvtf34OtIr6FmEr0FREpEFO53hh2jhYKtjU+7FqGX6vW1zWcbGB9q7m20Pp/sh4TRBlh21rfW60/h99Xeeo92cP6y6Jt93XruUaL2UR7Y6ri8rDr+rtWY9zesW1CRKKx7/D9qvpsW4/bW3DCqOszGxMo5wOzAFS1Evt1dz6Qr6prAcTsQ78BzsJUOcmYCkK848qBt7z95wCPh30pN2KqmuSwV4yqfrKNMeUDqSKSELYtB8gL+7wn08F/61yqulJVz8Yesn8FnhGzL+2MfOzBEk67zE1VP9KvjdDDdqePVjwGvARkq2oSpqpq+V83qep1qjoUmACcAPwI+z83YCvGlv9z4g7G829M1TZAVROxB6y0cXybMSHTwo68vjYCOdt5OLf+n+Rgq8nCbbRtCz1b7Fph/eXTtvt6e2zE1Mzh358EVT2ujWNqyz31L6AG+47vczhh1MVR1TpgPvArvl7FAHzsbQv3okvAvqRFQEBErgESW3X5GPZQOt1738LdwG9FZBhsNXKfuZ0xbcRWZzd5hvIR2Erk0d2a5HenEEhrMWoDiMgPRaS7mlNAubc5uM2jv8lrwEAROUdEAiIyDVOpvNLuo/7uJGC/5OtFZBz2AwMAETlcRIaLOSZUYmqtoKpuxn6Q/F1EEj3ngH4iMnkH56gEqkVkMLtmMH8KuEREenmr+Kt20HYuJrz+IiJx3n11qLfvceAyEekj5iJ/I/DkdlZRbSHdG1eEd48PAV77jvf1XKBSRH4jIjFizhsHiMhBbRxTITtwhhGR87AfFGd9h3l3aZww2jv4APsCfRy27SNvW7gwehOz/azA1Av1fFul9BJmdypU1c9bNqrq89gK4glPHfMFcOwOxnQ2pq/PB54H/qiqb+/qxNoDVV2GPbDWeCqSLMyutlREqoE7gO+ran0b+irBvvSXY7aHK4ETVLW4wyaw+1wEXC8iVZjh/KmwfZmYSqcSczr4APift+9HmJH9S8z+8AzQYzvn+DUm5KqA+4And2F892H35OfAZ5jjwTbx1LUnYmEKG4BNmHMBmIfhI9i9vha7ry/ehXG05lPsO1CMOQOdoV/Hl+3WfR02/lHeGIuB/2BajbZwE3C1d//+ehv7r8acQFbIt+ONJrXxHF0a+abq1OFwOPZdRGQG5ggzsbPH4vgmbmXkcDgcjk7HCSOHw+FwdDpOTedwOByOTsetjBwOh8PR6Thh5HA4HI5Oxwkjh8PhcHQ6Thg5HA6Ho9NxwsjhcDgcnY4TRg6Hw+HodJwwcjgcDken44SRw+FwODodJ4wcDofD0ensUBiJSJqILPJeBSKSF/ZZReTvYW1/LSLXtjr+cxF5vIPG7nA4HI59hB0KI1UtUdVRqjoKq3dzW9jnBuA0EWld9REAERni9X9YG4uaORwOh2M/5buo6ZqBe4HLtrP/HKwGyVvASd/hPA6Hw+HYx/muNqN/AT8Ir7AZxjSsENfjWMEqh8PhcDi2ybbqzX8LEckEzgAyvfK36wDBSuVWACux6oyvee0Pwkpf/8o7TkUkRVXLvP3HANdjJbHrgeXAFaq6od1m5nA4HI69hp0KIxERrPzuOuBBVb1FREZhteJXA4dhJYVTgWHeYWcDg4GDgSCm0jsd+I+IHAD8EzhJVb/yznESVuq3ywqjbt26aW5ubmcPw+HYL1mwYAEAY8aMsQ2qIEIoBFu2QGEhNDfbrshI6NED0tJApJMG7NjKggULilW1+87atWVldDjQBMxv2aCqi0REvfelIvIUcAGQKCI+4EzgZ8AMTFV3Biag/gP8BrixRRB5fbzUxnntUUTkfOB8gJycHObPn7+TIxwOx67QMGs+c3/8b6JCtQwo+IiQL0BB6jBytszj0WMfxRfwMaTgPQ7DhNFHPfsTXbAWFixg3ejT+fLLEKl1m0hIjSB4yCSqI1PZ8MkmZP1mUstDDJjSk9x+fqSyAsrLCQWV4vp4iotCVFcp9RpN7F23MHbqtiwNjvZARNa3pV1bhNEB4N0J2+dO4HJgFbZSygO+h9mLXgRuBHwi0gNbPd3SlsE5HI59m2B+If3WvEWzBvg4MJ5IrWfAxmXUqJ+jnr+IFC0hlbKt7eteeotSYnidGZwx7xmGR3YnYUwuKVIOr90EqkyIiaG6Ry+2FAndX3yNeglRG5FEpS+Z+gYhVmuIxk+sQLQ0MD//5k68Ao4WdlrpVURCQDFmA2oGHgJuB3IwW0+LQKsG7lPVX4tIJGZPekpVLxCR54D/quqrItIAfKSqR4pIGrbiSgX+pKpdVkiNHTtW3crI4dhDvPoqnHACxMTQ/PTzRJxwDAB33t5EfoGPqBgfU6fCIYeAr8UNq6kJamogMRF8Phob4Ykn4LXXYN06iI+HkSPh0EPtuB49Om12+xUiskBVx+60XRuEUR0wT1UPE5F04DFgFvAA8B6wFPgp8AEQi3nRpQFPY7FIpd72t1T1hyJSjTktTFbVpSJyBqa6e1VVr92dyXYUIvIIcBpAXFxc7ODBgzt5RA6HY5cIBqG6GqKjob4eVq2CQYNMMrENW1QriouhqMgOjYiA7t3t5XO5a9rMggULVFV3esXaoqYLAlEi8lNVvc+zo3wGzGxpoKqbReQ3wH1AT+BU4H4gqKq/8IJe14pILOZ9Fwn8BThxF8axx1HV6cB0cCsjh2OvoqCATT+/kR4v3YO/uZGqbrloZBSJQGFsLrN+9wax+as4dsEAAOZd8kvkuGNh3jz4+99Zf+T/8cw9JRSvr2Jzv0kck/MlH5aPYO7CAAfWbWTa+UkcProCf0Y3qKigaeES1tGHouWl1Fc1EUxOpfmsH3Ds8U5qichnbWqoqjt8AQpkAa947zdjDg3jgUpgkdfuMWwldCpQhnnGvRPWz3PYqmkd8AOgDvPGWwasAQbubCx7+oU5L8wH5ufk5KjD4dhL+OtftVn8ei8/0XN5QBuIUAV9j8mqoKfztC5ngHrPNNWwV50v5hufd+dVR5QeNinU2VehSwDM1zY8b9uiplNVFRHJBT4FqoBuwCAsRdDRmOPCMOBZTGX3DvAlUKWqv2jV3zpgLJaV4VDgdeAEVZ3RFuHZWbiVkcOxF1FTQ8kXm6nN6o/PBxFPPUrEpx+Tf8lfGHjyECKKN6OBAD7PH/z6Ez4ldva7VFXB870u5vIRb3Pyz3uRNCAdFiyAYcNg4UJzJ+83gE/eqOSNTxKpWVNIdGIkEePHMLnPBvqNSyOtZzQNRZU0ZPWhZ89Ovg5dgPa0GYULo1eAxZggScBWO31UdZTnpHAktsp5CFsdjd2BMKrABNa/gRFdURiFu3bHxcWNcTajvYzKSigthVAI/H4zAPTsCZmZwLbtBUVFsHmz2cL9BAniByApCbKzISpq+6cLBu24yEhnU3A4WmhPm1E4fiAbc0Bo3Xmltz9SVW8TkRk76khVm0TkNuAqwuxPXQlVvRfLv+dWRnsTs2dTfuTpJNdupsqXSIPE0C1YSFmgG43FPi48cA6nVz7AdPudwROjz6JxyXK6zX+dRc0HUJ41lOMi3yF+3VKahxzA4sRJLPosyOAvlzI4MZ/YqROIjgwRqqqhuD6O9XkBVm5OIL18Of1ZBcBdx7/Gza8M7cyr4HB0CdpqM2rTyoivhU8A+CMwEFiIxQs1Yi7eOdiqaCRwE/BjzNYUwlZB9Zid6WNsxVQsIlHAWszTbsYuzXAP0Crodcz69W2K3XJ0NqWlrD78J7yS/EMWZBxHQzBAdFUR/bbM5prPT2dh7AQOrP2EluB8BWqJ4eOk4xmbspqUwmVIbi6ccQbMng1z5hAMRLIiMJQvi9OZyMfU++OoCCUQo7VE0ERqRBV13bKp7jOC8gph7ol/4mc35XTeNXA4uggdpaZrEUDPYsGs3YDLVfVBEXkQU+MNA34L9FPVPBGJB7qr6trvMJ9OwQmjfYzmZujb1/RwV1+NXHstAO+/WE52bx99RiRY+hgv1cxWWr4jInzxhYXArFoFyckWrzJ1qqnxHA7Ht+koYTQLeFFVLxKRV7AsC+e3EkZrMKeEJcBxqtr4nWbSiTibkcPhEQpRV1KLhEL4ayuRYDMaEYm/roam9B4QHUOgoYZFa1YCMGbECGhqQgu3sMWfSX5JNKEQpEdVkN6Ux5ZQdyqJJzmumZT0CGJ99RAXZ8E8qmhVNU3NQrP6CQYhIEECibFERDlj3N5GW21GuyKM+mIro2mq+oaIHItl6d6IBbbmALdiKrrXME+5IuCX2kVzz+0Kzmbk2K/55BNLXQA0EkE5yaRTRB3RfMUQNpLNyby0VfVZ7U8AIC5YRS0xlMf3ont8HRGFeZCQYM4lrajxJ7A0cQIDK+aSHCr71v4nr1rItJtGddgUHR1DW1dGbXFgCInIWiyr9hzgbW+V9BqwWVVzvBPeCWzCctllAEcAU4F7ReRZINZzWhgOPKqqI0TkfaAHFnMUhVWSvXdXJtqRtE6U6nDstwwdyoI/v0EwMoay7OHURSZDTQ1Zc55j3L/OZTQLWXT4pfDe7QAsSZhASnMRb5x4F9Mb7iMrsgZiYswl8cor4aWXoKGB+pQezHshjw/W5zJp8Z30qF/L571PYtPBZ5DeK5KM2CpiokJU+ZKYcGLfzr0Gjg6lLSujakzw9MKyK/wdeAmYh9UjSlDVRk8YzQceBkqAHFWtEpEnMVfwyao6V0QuAEap6s88YfRrVZ0vIqlYEGxGV1HtOZuRw7ETgkEYM8bUa7NnIxERAOzsueLYf2jPlRGYyu1w4E3g15hwKsVcuc/F0gC1kIllVTgYC34dA6wAJgBzvb/vbOMc8UANln6oy1FSUsLYsTu9no79lVAI1q6F8nIANCEJqaoAEXTESCTgh6YmFixeDHixTaEQNDTQEIpgzVohpaGA5vhkgtFxlJaa30TvrCbSMgJduzBPIGCDHT9+a8yW+644whjdlkZtEUYB4A1VXSEim7HM3S055WKBf4rIz7FVUzKWPDUTeNxrn4ZlZfgZlu17AnBdWP+Pepm8BwCXqmqXEUYuzsjRJmpraZ44BSmv5O9cQTpbmFH1EHM5iHE6j198/n+URGbx36bpxHmHPH/Cz8i67df4K8upIJE8f2+GUgDVBdC9D83d41i+OYlheQuoKUwk0CebqJLNFrRbUAB+P83xSTSVVNLYoNwV+CUH/O8qTjxxhyN1OPY4bY0zaoswehd4Q0Qew+KLmrHkodHAMcBbmBAKAGmqul5EnsGK7cViqrx/AP1E5A6gO1aOvCUzw0pgC2Zf+kRE3lDVLqEPczYjR5uIicE/dQr/SLma4JEnoZnw+MbfU5rQm5xbJ3Br4W+IbKxlecrBUPYpANnX/YTlDOR67uS3qfcwrHI2PPIIrFwJq1cTqKhgaHQen3b/A1+9m0fqyiIau00kpyifoojxVFQoEQXlVJCEP+DDN3wQqamdfB0cju/ADm1GXr2hTVjAazVQi8UIngM85f39IyZgZmG2oTOwlEHrsJXQxcBQLIv325hab463Pc9re5yqhjz70rOq+lQ7z/M748qOOxytCIWsPENcnKkRGxutVIPHttItVVTYwq6pugE/QRp8MaSkChkZ3zjUsQ/RXumAzsDsO4mqOhlARD4ABLMZgdl5ioBjsUzdPVV1lohsxMqON3jtZgOXYnYjgDuACOCPniCKBQ4EukzZRVd23OH4Nnl3PE3Jv59i8Po3iayvojK9PwjEFa/nlb8to1vNenJWvkuOJ4zeuvR6mm+4idr1Rdxb/yM0JY0/+S4mEGqi1p/IE2XTKClJ4aBBlYzuW0Zi92iYPt1qDj33HMybhwYCNA8YyoaSOOYXZnPmuxe6/H97Ce2lpjsb+ApL5dPCs8DvWrX7MxaDFAI+9LbNAk7G1HpgwuhGrNTEz71+vwQe9gr4RQEPqurOSpw7HI5OpOm1d0hdPpuHOYuPmMRft/yGIH4i8ZH2qx8xntkoXztcpE4/njKSKYo6gBv5vaVQnjgRLrmE2BdeYMYLjxFsaKZsWSIFy5JRXxFJDz0EQDN+FkcdhDY2M+Tte8mhiTz/JFavvpABAzrpAjg6hLbmpvtKVYd6n+/CVgvVWAmJK7D8dNGY7Wcz8AbmUfc3zGa0CSszcR1md/ohcAhwo6r+ud1n1QE4BwaHw6O2llBUDIVbhIYGLIDV7yflr78h6ZF/UZ/dn49uW8D3zrAcSTPPuZf4U45izOm5+DZtsFIMRx0FsbHf6LagAB59FGa9XUvvZW8Swkde1kFE980iM9MqrA4ZAkcfvePs6Y6uRXuXHW8G0lW1zsu8cDPQDzgOixM6QUQ2Yaubo1R1kZe1eyxwgvd3OPA4pp7rCfTBEqcepqpLd2+aHYsrO+5wdBCqsGyZ1fMeOnS70mVHZcHr6uxwETs8JqZDR+zYTdq77HglJkTOx1R3rwC/bNWuGVsp/cZr8w1U9T0RuReYgnnQFWFu06+KyGGquqENY9nTfAQMAUhLSxvjVkYORztxyy1wxRUEA5FU1kdT2n8ywZh4RKA5MZUtZ/2Cnms/ZsD/TQZg/g030BwZy5b7X2bFMuVfG07EV1RAGiVUkshyBhHomcnFExYwZVwtWX2jbeWVkAD5+YSqaympiqSwPIramhDlmUOIGTuMSZM6+TrsB7R3CYm3sYdyEPOci8QcF07BPOZ6AklYOYgcLMjpYGxF9H1MSxzEvPJ8mBovHhNqCZiqb5KqluzCHDscl4HB4egAamuhd2/m+CdwV+HpPMy51BNFJI34sOfRE0zjTJ4mQAiAlqdUEwEUIZKm7zSE6/kDs4+5ntdf/07dONpAu2btBhZhzgl3YmXGx2JpgDK2oY77Bya8FPPG6wEc7dUvuhy4AVPR/QV4RVWf2a0Z7mGczcjhaEfWrCGvJJqSqCyaSysJxiZAczOq0PeP0+n27pNU5BxA8oYvAPjHqTNJiqglZepoDp3kI3X1PMjJgfR0KCuD5cshL4+i7NG8OS+VJfMbKNtYTUxTJaHMHmT0S2BgbiO9MxtISPJBRgaxuem4aI2Op73TAb0O9MVqGc3CAmFP2UY7PxCHrYSSsRXSD1W12NufBHyOedN1eVrZjFyKE4djT+HZiMZ0t78PbbjCtq/Gy4myPR74+m209yprhPeqrPR8VBR89ZV5Q2RnA9uxS6lSUysUFlqGp5bf7DExkJEBqaldO0NTF6Pd0gEBPIGVhrgRy74wk28Ko2mYoFmCVX192WuXCiwAEJHJmMrrT1i2hW/nkO9iqOp0bB5uZeRw7G0sW8b6Cd+nd9mSrZvKI7qRrEp1aQPTR37A4bWvsoBpALzXFE3VcdPwv/w8qV9+TIFmUOlPoX9gDdVZA/FXllFQl8yqdT0Ztmk5kRmpJKUIUXERaHQM8uVSquIzqWqKQSrLqW8O8N5Zd3PBA+M76wp0CdozHRCqulhEMjDbUA626okTkTzMFhTAYpGGYe7b/8BSBUUBhSJSg2X0Ph2zOal3TANdGJcOyOHYi8nOpikhlXvTb2FW7Pc4bfOdnFxwLy9kXsgpBXdz24djyG1YvtUTq27xCrIWX8JXDOb5uIuZkruOQRnVBIYcRtSqVZA2hKSCAnquXsdntaOoz6tE8pQoGkigmC+YSmZRAZE00Rg/iPjYZmLTnItfW9mV4noPYquEE7D6Qy1JRIsxW9Eo4A/YwvhpLNP3v4BrgXxV/dLr73osg8NxwI+6qlt3a9zKyOHYy1GF9euhd28LWFqxAm6+GbnCVICvP1FOaMMmuk8eyshRQmTkjrvLz4c5c2DjRvD5IDMTBgyAwYNdaqNw2tuB4TDgf8D/VPX3IjKFbwqjg4GDgJ8AZwKXYyuo8ZiAOkZVS0RkFPAq5on3tqp2adtR+MooLS1tjMtN902CQcjLg6Ii059HR0NDg6Us69YNevUyNb3D4dh/ac84I4AXgSmqurjV9sswNV0voAIrrLcJi0laDryP1TKaLSIhoAo4W1U/ZC8jLi5un81NN2cOVL/wDkPy3yUubwUaF09zj2xqJxxJ/cGTicxbS/pfLiP+Hase/+Wtr1PyzHtsmL+FgsZUho2NYXKvVURPHk9NWg5z75xL3NyZJJbXETN+BNnDEvE1NpjBOCoKqqqgtBQaGymKyWFjfXdG/2AITJ3ayVfC4XC0N+0dZ/Qq5sfyJiZopmKCZzJWh2g98AwmkKZjq6QyLClqS2j1WuBqVX3R67cXpsYbisUevQJc0VWqvML+E2d08cVwwp1HcwQzWUV/4qghi3wCBNlANmmU4CNErJeiUIEGIqmMTidNi/E1N5mOIi/POvT7qRwxkc9WJTCwagHRvkaIiiK1Lh+AUCCC5oRUmjRATHk+PpTgaWfif7bLJWt3OBzfkfZW08VhZcYzgXGqutorGT4QuEtVbxCRnwHXYNm8z/VKia/DVHjLMIeGp1S1t4gI8Cnwb1V9QET8mMqvVFWv2L0pdyz7ss2osRHWf7SB1RXdqJNYQiGgro6c9x6i+7KPaIqM5fPjfseZV/YFYPb1b9Fn+kQycmNMV9fUZDq6jRttxdOjB6Sn09wML75o+cbmzoXNeUECNNNIJHiJNA8a1cTzD5TTM0stZsThcOxTdITN6BGgCfiLqv7XE0ZNmGfdOOA5YDBQCDyPedStxVIDvQwcD9yjqqNEZCpWOuKwsPMkeu2zVbV216bbMeyTuenKyqz+zDass9uKtygvh3XrCWN9AAAgAElEQVTrzA6UmGiyp7raKk3n5EBKyp4auMPh2BvpEJsRpnr7UERagljHYVqblZhTwt+xjNzHYYGtWViA7BasHPlZ3nHD8OKPWlDVShHZAPTHCu51BfaJ3HT65FM8/0oEY7e8Rs6C/6B+P9WTjqPsB7+gKXcAOT+aTPOUo4j1hNH8c8+l7oU3mL2lHzetPpEre3zMtGMqSUoWCAQoWlZMxdvzmLVmNPTtx9SJDfTKbIaaGgsmTEgwKVZVRU1UKq9tGcthNx1LRkYnXwiHw7HH6RCbkar+0tt2LTABKzm+ARiB5ZcbBDyI2ZL+B0zC3L7LsRVTDJAO3AMMVdUDW51rETBdVZfQBdhXbEaNo8cTudDKXd/GpdQTzbk8RBab2UJ34qghjtqtFWgUWEsu2WwkQBAVQeLibGdzM8TFETpwNI2z5hFdV04zfkLipykyjtjGckSVEEKdP564YBX/4wcEH/wf557bKdN3OBydSHunAzoLeEdEfqeqN7ba9zJWt6gZq3EEFod0AGx9vh0FbAR6Yw4LedhKK3zAiUA25ijRJVDVFvd1xo4du2Op3YWJ/PQjat/6mA1z8skZeQ7BkDCr6TpGPnolfd+5h/cveZ6K5ji4w7SmV569kcQhPZkxYQW9qpchRxxhq50wfEB0MEh1lfLI4wFeeAEWLIDqknqiqScmPZEBg3xMGNPAjLNqGXxIJ0zc4XDsNexK0Gsqpra6FRMaE4C3VPUWEfm+t30E5lU3Dsvm/RNM+NwKrMPKS+RgJcpvxmohPew5MNwNVKrq5e0+y91kn7QZ7Sc0NkLD5lKIjYHoGAQloqqUYHQc0Xmr8TU1gOpWXfGYlBQoKyOUmExJTC8qihqJDNVRH5tGVJTSUBOkqTFEbJSS3juaOH+9GdB8Pguu8vvB76dZIqhtioCyMhIzY12RHcd+T1ttRm0WRt77bKys+BzMIaEKq0sEJnSy+FoYjcdKja/FCvEVYMJmpJfpewqQhjk9+IDXMOHUZVIE7Stquv2RFx6q4JAZAykkgxk8yP2cxyg+37r/GF5nGk9yHg8Cppp8LnAmxze/SBRh0QXx8eaxsQuEEHwoZRf9npR/3dAOs3E49l7a05uuGnMquB2LH2oAIoBnsQJ7y7H6RtlYZu9hwDuqGhCR+Vgs0WVe+4OwOkaDvD6WA+ep6vLdmOMeZV927d4XaW6G8sdeo9u5xwPQkJzO8p/cQuoXH1Cf1Y+NP/wtscsXMv5nllD45am38e7wS+kfk8eZwSdI75cAw4bBf/8L/fpZCpnISGobA8z7z+c8saA/y6p7EUcNa+lDkr+GQ4aUc0TfdQxPWEvCtONJPv5QxOdSOzv2b9pbGC0BHlLVu71td2OZFyar6gEiEsDsRRdgAbAtwugaTGB9BCzka2H0PtAN85o7QVVP2q1ZdjBOTedwOMJpHf7Q1ATFxVBZaSmx4uIsFdZ2qqjvl7Sna7cfaGoRRB4F2MoGAFVtFpEGrGheuC7rfiwrwze85sL4ELi0DWPoFFwJCYdj/2Dt26tI/tPlxG5cRsnlNxGxbiUN/YZSe/jxxDaUkfnP3xOI9CGeMPrwvF9Q+4ebyCuLZaYeTl3vQYyu+pDGgmo2FOTgH3sgxx7vI7d4vtkTs7LMflhaClFRhDKzWFebzpJZlURmpjLoxIH0Pbx3J1+FjqG9XbtD3kuxQnuLMEF2DlazaB0wHFiKJUZ9BnNeGKuqv/AyficCR2LCrRZT0b3otZm2S7PrBJwwcjj2UZqaKE3pS0RNOSWkkRv2e/orBhPCxwBW0iDRJGoVYA/CeYwlOj2RYeWzLPdijx40pXQntHI1UU01ANT44vH7Ibppx3bHR1N+wQ9K/9lhU+xM2tO1uxFL+XOZiKQDj3nb7wN+jdUxCgHXY3noTgHeaNVHT8yJYbB3fBbmVXcocHEbxtApuHpGDsd+QEQE1Xc9wgoZRHkwgY2fvU5Jv3Gkr/iYgW/+g6SNX/D02a8wu2E0PNEdgBcP/SvZd1zB8DECtbWwYQMMHEiEzwdNTVR+uZEXnmrif7P7seRLP82VtaTF1CJpqeRkNjI2cxMTBhRx8FGJ1GwsZbB07+SL0Pm0ZWVUB8xrSd0jIn2xPHVjsKwKS1X1BC/f3D8x29EkTFi1rIxKgD+p6u1eGqFfq2qXX2aEC6O4uLgxzmbkcDi6Ktssn+7R2Ggys7kZIiLMthVoa5Tpdx9Xu9mMgkCUiPxUVe9T1TUiEoEV0wOY5GVOSMNSAk3EypD3ABCR3lj+umd3Yx6dSuugV6emczgce5o5HzVR89AzDFn0OHHF66nKHkLpoAnElWwgmJBMydSzSKneyJAFRwIw79jjaPZFsjmUwaZZ65i7IoUH8o6iN8UUkEkaJWTKFvodEMMpfRczNHIV8dWbkcpKaGoi5AtQH51MeUI2+UlDaCbA+EvGwUEH7db429tmtBSrWRSDZU/IxrIyPIl5ybX4jgzBsi8UYRm+6zF70iAsAWrF3roycnFGDoejM7jiV0Euuy2bED4WM4LhLCGbTdQTRTRfh2WGp/NqoRk/AYI77D+fHhT4sqgJJNEQikCam0imnL6sIYVya3TddXDNNbs1/nbN2h0W9Ho0ZhvqTys1nbd/LtBNVft6ga0tarqPsCzdM3drNl0AtzJyOBydQUMDlH22lqLY3gTVB6oENm+kISkd/8Z1xCz4mKrINA668TQArrlGiQ00MiQpn9HHZdIruB7mz7fSLoWFkJQEWVlodQ3LA8N4b2EyK1danuOoKHNNz86G7F5KbkIJmRlKfEYcxMbu1vjbOzddC70w9+07t7M/Cav02pqbgJtF5ARVLRCRKOACVf3HLp5/j9LKZsTYsTu9nvsWK1aYonnYMFM074RQCDZvhi1b7L3PZ3/BlSF3ODqaFlvRq6+GPace7qTBfJPRbWnUJmHkOTH4vPb/AK7DvOHga5uRABnAb1sfr6qviUgGlmxVsJXk/W05d2eyP9uMZp/wZw5ZcDXq81Ee25OqkROp7zeMyonHEVFfRY8Hb8InSveH/g7AzPFX4V8wl/ym7iQNzGD84HKSE4JUDTmYJxYMYP0LCzm14iX6ZVSTfNBApE8u1NfbT7HERIsaLCoiGIIFxb1JOfMoBvxkcmdeAofD0Q60q80oTE13CBZD9DxwC1ZW/GZVvcXb/wEwEqvg+i2htLexv9qMtK6etfEH8GnoIJYwnBv5/dZ9eWRRSyx9WEsTEVtLkTcSYH3SSLJjioiqKbOqe6pW/dVjcdx41takc2BgCZkUoDGxBIIN+GurCUbFUBGTSW11iMzmTXw04SoOn+XyujkcezsdoqZT1dkiEo85MmyLFMxh4Syv3MReW3YB9p0SEruKxESTvXkejev8dCuNY97iQ6jMOYDEL2fT+9W7yF6ziE9+9S6FfcbD9GgAahatov/IbUSQr14NRUXQowcHZPfmq6dhxj3w4YcQtPhBfAQJNfjwNQmHHgpXX9nIUZMbv92Xw+HYZ9nVldFgLMboYayGUeuVUQGWUPVo4HeqOrsDx97huDgjh6MLoMqCz0zTM2bQIKiupqE+xIaqVGhsICqghCKjKKuLIaSQkqz06gmR0WFJaoOeR5kzWu5x2rXsuGczaqEKs/kEsIJ6LW1isJXRR0ApcDZWQmKvZX+2GTkcewKd+R7rjrmQtckHEhUtbEnsx9tDfkltXHcifc1c/N5p9C6aR5LXfv5yS/BvZTo228Zme2l8PDUaS0x5Mf7yEDUxaUSnxuIvKTL7JBCKiYX6enwaopIECiN6sfi2mZz+88w9P/n9hLbajNokjFQ1xuv0OMzxIB74ExbYmuY1OwH4AvgYy0H3BxE5CXPvLt6l0XcRXDogh6NjafRFU5o5lEFb5tJc7uOQjU/yvS9v58GEi+nduIrh9S9TRfzW9tN4gtW5R3LB9FpmxD1NxKhhkJ4OS5Yg8+cT39BARXQ677wfQeHiAuLya/Gnd6M2pwelpRBZnEcdMXTP8DMws4K40o0k90npxCvgaGFXKr1OxVYJdwNnYt50EcBcVT1WRJ7DBBJAMZZ1oRI4YG8VRuG4lZHDsQdYtgz+8Ad45hkLJ7jySvSsafhGjgCgvFxJStpJH2FdPfywhdiUl0PPnjBxIpx4Igwc2IFzcHyDdg16BQ4DHgKOwyq4jsUEzuF8XVBvDTAfiMYSqA7H3MD77K3CyNUzcjh2QjCIFm5Bgs2QkADJydtstjVv2oEHEiqvpLgmmpIiJU2LSfFVUh3TjYKGFOqaI0hJhewezQSidx7b5uj6tGvZcaAMmKKqi1syK2DCaAKmqnsCy0f3d+DHmDBag6UFylbV/N2fStfArYwcjlasWYOOG4eUlFArscRqLWtih7E4YSKvdf8RvepXc+m6X1IVkUavulUAVAaSSWgu39qF+v3IiBGwcOHWbS1l2ytSc4kfkIW/ptIyfAKhzYVQWYEiNKufHwf+xymPnslZZ+3ZqTvaTnu6dtcBnwHPi0gIq0f0mvd3NWYzisGE0uXYSulRvs5Xt9f66DqbkcOxA/r0ofHMH3J/83TeKhjJyFXPcmb+7RxZ/DgnbvkPirAq/kA2R2SDJ4xmJR3H8nE/4uRR68gdHINMmWK5Z2bNgqVLoaiIok2NPPtOMlmrPyRxXjWSmI4GIqirUdbVHUEZKaSmKP1zgxw8aiCDBnXuZXC0D20tO74MS/XzAPBXzHY0DEuS2tt7P19VT/cSoV6BrZKGAoP3YjXdVmGUlpY2Jjc3t3MH5HA4tlkqoaoK8vIsvxpYKqrUVEvHFhnZGaN0tNDeZcdrge9hbtuFwGXe36VYYb3fACvCjvkxpsbbcXnDvYi4uDicms7h6DjWf15Opm4mSuthwACIj/9mg0WLIDcXSTHvt/k33ED90y/x4cIE7lkxjmO71XPa5E1EZaYwKy+Xx99Np7Eyml+eV8rZ50YSSE+1eKPqakv6mZwM0dEQCpG3up6kbhHE53brhJnv27RnOqAGvq70mg18CFyKedXNBfwtWbu99gswld0BmHpvr3XtDsfZjByOjqO+HhbEHMqhfAKY3WihfywvRn+fZxLPY2LoQ+4tPJnSyAzSGgsBC3asIp5o6on4OuRxt1l78PfpM+fx79yP45u0pzfdLzFX7hSs0F4IuAB4HIgEErFM3XdgtqJ13qHh2bunqGo5exn7a246h2NPU18PH1/1MlX51VQ1RJKxZQmD1r5ObuFcmn0RhMTPprjB1ISiGVE9B4ALUp6k/uiT+dVF9YxIXGernKwsKC21nIhbtkBDA58uT+b+uxupLywnLtFPaq84gtV1VG4sJ0rryezhY8S4aA6cNpCMs4/o3AuxD9Kewuhi4M9Ad1VtEJFuWHbuxcAMzIvudCAXuAoYCDzfkiJob8a5djscjtZ8w2alCqo0BX1s2gRlpeoVtxMCAZON3bt35mg7n/a0GeVhq6FpWE66MuBWzMuuEMATUsOxjN2v7u6guxqqOh2YDk5N53Ds68x6cCVpX35EWt5iAuVF1A8aRdmx59Cc0ROfKJkP/5X4yCZiPGE0/+ij0XvuQUpK2OjLoVDTGRlYSkCbqOoxiA+aJ7B+QxR9ayoZNyFAt4P6WCxWUZHlyEtPh2CQ+tJa1lWlETF8MP1+fFgnX4X2pz1tRndiK58ELAtUPLASmOVtDwAvAj/AMi7UAamYSi8ayFfVnl5f5wO/8rquxsqPv78L89qjODWdw7H/cH/SZZxXeTvVxFFCGr3ZQBAfb3I0KxjIpdwBfLO89xtxp/FxzYEckrKMyYMLiR83zBwvPvsM/fRTGhuhsDaBQKiRLC+XXsjnR1CkpfKkx5ak/qSXr9yDM94ztKea7kzgLOBfWMaF32P/h/FYDNHLQAPmtLAaE0zVQA1mW/rYKz1+AlaU72hVLRaR0cBLwMGqmrdbs9yDuJWRw7Fvs/qdtWzZ1Mjm+AHg8xGXv5LeHzxM75n3E1Oaz4bRp/DepGuYcYcVLv15n1fZcMBxnHkmnHPO9hOCV1TA3/4GD93XSPWWGipJRFC6+coYOtzP5GNimDJ0C6N6l5E0edQenPGeoT2FURaWf66Xp4r7JxY/NAhz+S7ESkZ8AjyJCaIVWJ66t4AsTxh9BPxRVWeG9f0nzBvvd7sxxw7HlZBwOBwtbLUVjR4NNTU01oVYvyWG6nof0TTQQBRB/HTrZnG8vp1aSfYP2tNmlAAgIjlY+p9azI50PpahezHQH2jC0gJdhQmoIJAPZHn9DAMWtOp7PhaT1CVxJSQcjn2b1V81UnTTfxj1yg34GmopGjiRjcOOIb/vRMqyR5DYWMzwT+6mW9VaunvCaM6WEgKbvlbZh3x+fCGrl1SU3J/ZxUPx1UYxqW8+SYMyIS4OamuhuBhqatCISCrLg9QFo1g/+lRG33IOEVn7rpdDu9iMvLiiOVhqn3ogDrMD/Q74OeZVFw8swoTWUKAAcwMvxuxHMZjAOgjLU1cR1v8pwAxVPWXXprdncDYjh2Pf5oU/L+Wkq4fzMRP5iiFM5V36sxqAmRxOBoUM4SvKSKEbpQB8wCT+ycWMOCqTyw7+hHiqYfhwWLUK5s+nZslqitbXsq6pJ/3iC0mNroPYGKqju1NYE0f5lkbqm/xkUMhIFlP//OtEn3JMZ16GDqVdctOp6kYRuQM4CQtgPRurY/QQpoZLBb7E4otmqGqjiMzB1HbrgTuxpKq53ucxwMywU4zGVkddkv217LjDsb9w9K+GkT9qIXEZIzg4IARjYGPhWuLfe5kpf7kKgOW3zmR5xmFwuhmFFv/zQ647AoYOBZj0rT7jAGrgf7fBabdCWVjIf0oKHHsmnHYaDBgNeau/osek/h0+z72BttiMIrC0P6nYqijVEzpLgCFYHM7lQJqqHuBl9b4UU9UtxlZGuZhN6VTgGFUtEZFRwCPAEapa1AFz+8643HSO70IoBJWVFntZVWXbYmNtu1d4lKQkyMz8duYbh2Nfod1sRqra5GVheA14TFVbsnA3AeXAK8BdWDlysAwMm7CEqvcB73jbP8HKkc8SkQCQCYzsqoKoNS433f5NcTGsmVsMq1ZRUhtDSVUk64LZbK6Kp6wMGkpriCrdTFFzCu8stPxmt3IZyZRRHp/NhMPqGdm7jOicDBg0iNJyH++9E+TtmX7ylyfQa1gypx5Tx/hDhISoRmhooEkDrFrjo6o+gsT0aPoPjyFw0IEu86djr6Jdy44DF3l/N4RtiwTuwRwa/gN85W0fBRykqh+JSCFmSxoHRKjq3cDdnjB6ALheRH6oO1uedRJOTedo4Y034IXp7/MMZ27dVkc0b0WcwKqEA/lJxS0kBcsIin/rl+pi/10EE1OIKiuAudGwItkCHoNBUrEgvdNbOlvqvcKIwFQP36Cw0IIlHY59jJ0KI0+ddhgwD7hIRP4BdAcGYEX0FAt4XYrFIoWzBrM3fYqtpABQ1Wa8zAZdGVfPyNHCEUdAz8cmsjTvNZIi60iMrCd+ySec/MzTsOUZOPRQOP98/F98YUElQKCsiEBCgunlWvx8a2thk5e20e+3LNJVVWhZOV+siWHhAmX95kgaiCIrvZkhg0J0T26icks9hxxYvzVjtcOxr7EzbzrBvOn6YW7dH2Fqtw2YIDse+BnmXTcQmILZhX4L3IzZkyIxldz0rpxtYVu4OCOHo5NoamLB4sWAF9dTVUVTfZANpfGU10QQE2N2tpoak+9RUZCTDYlJYX0Eg9DQABEREPB+d4t8+1yODqW9bEY/xVY+L6rqChFZDRwInINl6X4cE1CDgNeB72PZGFKACzHvuSlYVoa9Dhdn5HC0P9ddB8fffiTRCREEI2NJqCvk80HT+GzEDJqiExi/+F5Oef2CrWl3Xq+Lp/tKMzvUEU1jZg6JW1YhwQD07k1xcn82Liln5Ko5VERnkJgo+KvKoa7uW+eu9cVRHteLrL9cAhdd9K39jvanXWxGqnqviJwMbBQRxbJ3RwHHYSq4ZcAZ2Opni6r+VUQuxexIghXkG4VlYviliNyOxSV1B9Z6p7lIVT/ZxfntEZyazuFof9JSlaKInmTnf06s1lFNDKfmX8LU937PIjmQQ/Vj1tEbiwaBuK/mcWHgP3SfOoKr0u4jqaoADjjdVj5r1tBtzRpSh/n5JPLXrPq0hGCxj+79kojJ6c4aX3/y5uYRrKiiW3KQfmnl5Pg3keXUnV2Onanp0jDPuBBW8bUBqMByzr3K1w4NyUCDqmZ4wui3mAP+XEzoTFDVOq/PKViC1BPYi+jWrZs61+6uR10d5OdDuVctKxCwlP2ZmS4di8PRFWgvNd0ZwGPAMViS1Jew+KFrsJVQLoCIXAFcLSK9w449Eftpk4Gp8Rbt4hw6nfB6Rjk5Oc61u4NoqGkm6pVnrSDa+edDYuLXO2tr4eab4eSTkdGWoDL07HNsnrOeNz9N4oPP/PSJzif35EFEDevPG3NTmflOkBSp4Tc3JvO9Y3wmsaqqIC/PCq/V15uRYcAAGvsMojEmycX5OBwdRHulA3ofW92kqer/icgnWD66szFV2zLMdTsWizdaha2ebubrjAvjMdfvw1V19d66MnI2ow4iFOKrmAMZ0mjG6mJ/OrNjj+TthNNYGjWaPxX8lAl179IokUR5IW7t7WM/7+Cfc9CcO9u5V4fDAe2XDmiKiLwKzGtlMzob+NBrVo3VORqkqj/11HQ+IAdLFXSfquZ4g5oI/BvIFpFlwK2ek0CXxNmM9gA+H5uP/ykf1PZkY1MPTlr+NyaWzOTE/McACImPB8bcSf/i2bD+UQDuPPFNko4Yw3GHlJGW1Aw9esCKFbB6taU88Plojorj/RcreOuNEMU10USlJZA0JIvqqDQWLo+ldFMNwwIrOHXockaeOqwzr4DD4WD3bUbnAO+oarTX7hfA7aoaaGUzaslDdzKW6XsultvuZKxk+ZvANara5avD7s02o1DIMggUFkJj49fbY2LMtpKa2nljczgc+zYdbTPq0ardCCw10FY8V/BTgQ+AI4BE4EGsSixegb0rgWvpoqXKW6+MOltNt3Qp5D39CTlVS4muKiKqJJ+ycUdTdugJxKz+gvQ3HqZ04kmM/IWVLn7p9tUsWBzB/Oc2cET5bCZmrCJnQi/ic1LZsq6G+XOCfLK2L7lNQab9JIHRUxIRv88s/zU10NwMDQ1oeQWr6nuxaVk1hx8VgOOP79Tr4HA49h7a22Y0GpiKOSG8jWVkOBgrK+HD3LjPwIz9J2KCZylWCTYHU/MvxnLYVeDZjEQkCVirql3yt3lXKyHxl79A5m9nMIOHAKghljhqqSSBeKrxedaU8LLI4WhqKlJa+p3GEBo1Gt/C1mWpHA6HY9u0Z6XXV7HYIB9mH/oCC2INV9NNw4rkFWCu3L/C4pBCmM3obhF5HnhAVV8K6zsJWKOqabs+xT1LV3BgqK6GzZ9tprgwSG10KhqIIHPmoySsXkRzQir5x5xH5szHGPif3wCQd9U/6N4riojeWTB6NGRlmSdZRYWlj1aF9etp1AheeKiCpx+oprwsRGxUiOi0OAqKA1Q1RtJrcAIXHr+RcUcm0G1MrvlOOxwORxtoF2EUZjOKwARNBrCZb9uMYoAS4ClMGB3U2ltORG4AQqp6Tdi2I4DrVPXbRUG6AOGu3XFxcbEuHZDDsYuEQrBuHcTFscDLyTdmzBirqxEdDYmJNDaa30ljo6XrS0iw30qOfYP2tBnNxlRpLa7dUXzbZjQRvPKIlgYoVkQWAUtV9Qfe9n8Bn4rIc6q6yBN0fwWub9uU9jyqOh0voWtXWBk5HF2Rohvu4Y25qSwedCYikFa1jt4Fn1IfnUyfjR8yuexGKCvbqj5+o9dIui24HxXhiaxfMS8vi+k8wlcM4W2OopFIcnOUs8euYMi4RPzJCbB8uXnaREVBbCxVDRFsfusLSsr9rOo2nmMemOYW7F2U9rQZxWK1jP6IuXYfghUzbLEZCaa+OwmzryQBo1S1T6t+fu319XcsNkkwD7x/79LM9iBdzWbkcHQ5gkEqxhxB0ucfckfgcho0kkuDtxD5dZJ+HuJHLGE4f+cKwGyZN/B7+rKGc3gcgLrBo4jevBapqPi6a3z4CQHQ9P/snXd4leX5xz/P2SebLJKQhISEPQWU4QIVrYp7j9Y9qv6srda6aq21Wuto1TqKdVTF0ap1i7hQURRZsgkJYYVMspOzz/3743kDEVCDHkiA53NdueC8533fc54jnjvPPb5fhwdn2P+tl24lnig2XrGfwbjFj1vOq4aeRqzTdN/Z2q2UsqObGp4ApqADEyJyVaf7zEI3LeyxWwuzMzIYvgO/Hy6+GKbrOTDOOANuuAG++greeovItCdo86aT3Evbdq869SZWn/9nBg2CovQmPXPQv7++T2UlhMNEw1FmrCzg5SebWfxFK/MbCom3B8jvE2H/QS2MH9HOficVsP84G3Z7N67d8IPEKhhdhjbG27a1+x/As51qRn9Bu7gOYS8KRsZ2vAcjsnVwKj19a5EhGoVAgPnLlwNWfcLyDGqQZDZtFKLBEMpuJyQOolGIj4OCvoInztgLGAyxJlY1o7PQrd0zrLmherRR3pWAWylluYSRDtxs/f0M2KK2ADqY7fEY2/EewoIFrJ5yBWkt5aSGaggqF67aWhqcGdw/9El+VvU0B1a9stV+oMGBq76W5Mb1LGQURbZykmiCCEhBARsTh+BeOp+kFY3U9D2A3HQftuYmHeQ8HsKZOfhXlOOsryIoTtZ4hrDo6qc47y/bebAaDIYdECsLiUmWDFCZ1ZCQjq4JPQYcCqSh7SOqReQ+64Wnod2Unei60NUdt/sR6zAYvo3XS9CTxNfOo5iRfCbLEsczuf4VTq3+B7d8cxpu8bPQPQ4CXwFQuaadKL34OPsqLm/5K57DJsFJJ0JtLerrr8lbsQL/0RP5qCSPlNKvKdmUTnyfYpTXTXBzK66SCsplPE2JufTv404jfDgAACAASURBVCOzbhkq1dgPGAyxpis1ozq0VYSg60YCXA9ME5EkpVQ2MAv4Ldpa/CFgsYicrJTyoLvR/g84TkT2qA4A08CwB7F+vZ6lysiARYtQHg8Aa9YISUmQloZO7X2P0+fHH8Mjj8CcOVrku6hI242ffDJMmGBMQg2GH0Msa0b/EBFnp2OfAC8DfxaRJOvYSegAFUI7wN4HjBeRKqXUWGA6MFhEoj9hTbud3WI73tiov0jDYYiP12JxycnfOmX+fK14MGjAftRXhWhrDuMiSIIrSNjhoSXgIhoRHB4H2XlOEpK+41tTBEIhLffj+KEMrcFgMPx0uloz6kpr98HAEutQOfAxcA4wttPx/wKnA4VAHtpq/A9sVW24WkS6lDfsqeySbrqHHiJ69a9YHb8fq/scygEV/yOzbS2laeOoSSyiPHUMc7JP5uG3dZd8qyX/80O0uNPxZiXhCAf0gVBIyze0b722HS8rXSOY/dc5XP0r8yu/wWDYNcTSQqIVGI4OPIXoWlEAHWTq0Nbif0en8OLQweoUERn9k1bQA9jVFhIybDhzB5zL7zP+yYY6L7acv3J6wz85tfkJ+jbNZuLa5zmD63nYOn/TQWeQ9/NJePqkQW4u9OkDS5dqSW6nk8CmOj59YRPlsytI3thCdqGHjAwIipO1tfHML0+lMppJcU47Y9LXoQIB8vJNIDIYDN1PV7TpOlq1E6zHT9NJ8kcpdRa6YeF0tEL3Q8D7ItKwC9/3bqHba0Zr18JDD2mfnj/9CYYP79JlpaVw553wv/9ttePu21fXPs47D0aO3HVv2WAwGDoTk51RF8kGKkUkqpS6Cy3v86n1JtzAZSLyYAxep1vZvHkzY8f+4Oe567jggp2+pKjo248//VT/GAyxpr2qhWhDI/ZIAGfYhyOy1TirutcgPJE2POFWlrbr31HHDBoEkQiB5gBNzYpM3zpCOPE7E7FJhLpoL1Ki9dgcduxpKXhdERSia6t2O2GHh1BrgEggjEQFbDYSB2yrUmboIXQpSxaLYPQfYLZS6mDgQ+BN4AOllEJ33j0Zg9fodtLS0syckcHwHXw45S8c8MGf2aDyWWUfwkr3MNbZC7nDdy2bmtwMjZbQSArp1vlfrSzZIvUDsCH/QHIyQtg3bdAHKtfSnpBBsC1ESnX5lvOiqC1WKR0EcVJn702O+f+zRxITbTrrRlvSdEqpY4AX0Z1z44G3RORlawd0GNpaohW4Ci0PtAo9hzQPuEhEQkqpSVh+Rtb97wD2B44XkcDOLnR3YeSADIbvIRLRXZrb9r/fdRfcdBOSkcH6maso2E9bl33S/yKa0ouwHzKRI8Lv4br1BkhK0tf4fDBrFkycSDDqYM4La/lofjJrK5y0e1IpSqplbK8ycg8bwOCD00lONXpAPZlY+hm1Wn89AZiGNth7AZiKFYy2Ofc2YBgwVkSGddauE5HpnYORUupm4AjgGBHx7eQadznGQsJgMOxS/H5tpWHRMcYxZsyY7npHMSdWckAd2IDHgWOAGzo/oZQaDVSJyCbr0AhgA7r1GxGJKKXmAn22ue5a635H9cRABMZCwmAwxIjWVsr/twjmziVx7ge0Fwwl6o2n4N9/pPy3j+A7/5dkOBvJHKDVPea++TYV4d4sf3k5iU/8nadtFzKvOo+kYB3h3AJOzP6KfkcP5KAT0sj0rdOajNGottgIh3WHbXIyktmbzTURGpdvwnnQOPr23f1Lj4kckIUb3bZ9ooisVNuPoWcCj1upOi8QBp5B76SwVBjGAb/qdM2BwEBgjIi0YjAYDHszzz9P4WWXAVBGP4rmvgvoeb/ke27mjHvG8BiXbz0/J5sQBUyiAjdBxvOvrbWyRrTf9vsQ/U1HaX7HKLSGWzpw49Vt3PVAz3Ut7EowcgBB4CJ0QLkY7fbqB94CFlqP86zzs9BzSMVKqSj6k2oCnlFK3Q/8wnqsgCOVUhvQu67RIhKO0bpiwq6eMzIYDPsIxxzDwj+9RXPRfqg+Ofg+foXkxZ+yacr57H/l/syNjiPscOtf5YEPD/4j+f4SGvomk/rHa3D9dzq4XJCfD2VlRMfsz6b3l7FmaTtfbB7Iuo12GhoV9nAAt9eGrXcGRRnNDEiupleawtkvn1+c0bNVV35IgeFy4FFgDVCLtpBYCNyFNsj7Czodtxx4FpiP3hE1A++h5YGmYGnXicgblnTQc+iGh5eBNuBiEZkd++X9NHaLHJDhRxMKQVUV1NZqpaMO4uMhJ2drPdxgMHQfMZEDArBUu+8CStBiqE3orrlT0EHHBzwN9AWGiciFSqkCrGBkNTGcBFwvIhOsBoaH0B12NejOuwNFZNHOL3P3YWpGu5hFi/jsqVLispPxpsfjGziKiFunFBLnfUTaBy8RyC0m/6HrAZjX53jYtImw2EnKiqNQyggOHskKz2g+/9JOQyOMKm5j0vFJpOW4tfdROKwHievqdH49Pp7GjGLW2AfQkj2A3EuO3m42y2Aw/DRiMvRqqXaD7igrQGcrB6NlgTLRA67no2eNWoBmpVROp1sMUUqVAO3AQKXUlcAyYB3aiG8SOm33hlJqsoiUdXF9uwWTptt9hP/9HAc/eN+Wx5Vk8RD/Rw6buIqHaSOOzE66fEmVqwjmFtIvP4w33AIFE/DMmcO49W8yzjonUOrCfb8evoy63CinA3JzaU/KorbeScumBvJ80xlNE2X044PCMhOMDIZuokut3daM0SbgM6AMmIm2HXdY56Si3WDvAlKAYuAa4HIRSfuO+16Ibv++IlaL2ZWYndGuJVpTR8W8SjavaSJcVUfhGw+QtmQWAOXH/4oV5/2FzK/fZv+/nApAKCQ7Fh4X0TMvQGWtg3v/2Mb0p4JUB1NQSmG36w0SwPjxcNaZwmEj6ohrr6PXxMH0MlZFBkNMiemckRWMPka7to5Hm+ptCUadzu2DTufdjA5G7SIy5Dvuez46GF21o+d7AqZmZNhjWbVqiyX7/E166mJMnz4QCBDOyqW+yU5zs667ud3atSQ11Xg2GWJPrOeMQDcuNInIEqvuA4BS6jDgSxFpR9eQWoE7gFvQnXd7LCIyDT3oa3ZGhh7HA9dtYNyzV/H7rMcJipOf1T9Pvr+EJkcaV7T+gdK4ERRvWrzFgn1eRQUAG+vcvMiZHOL9GhUXx7vhKQTXthNqzOTYw3zsP9GJd9RAWLYM7Hak3Uf9hjbW+noTXbSYDaEsWlypHBL+mMLZz0Jcz20XNnQ/sZwzircsx7OAsFJqYqcX8QH1QJpSKgJUoI31bkHXg4ZY50TQHXn/Av6GtqNIB0JKqVtEpLGrC9udmJqRoSdT+fVGRta+z+Pth5MY2kxaoJKIsmOXCEtTD+baoe/xzJxiCOud0WNcxjsZ53OP62au3XQ/qu9AaG9n//Uz9A0bgVetn04odCokDWghgTG0YUOoT+qrG0KG7DD5YTDsFDuTprsNyAEGisihSqk2oFxEhlnnXQZMRM8jtQCPishvrOcGAmtFJNBxP+v4v4ESEfnzLlpfzDA7I0OPZMYMOP54KCyEZ56B3r3hvvvg6quhf3945BHUlVcCsLk2Qmq6lS1pa9M7GhGor4fERKiuZt7yON56oYWmr0uYFxxBci8bRUPcjBjnZVzfKooOzcXrq9dmjQUFJq9n+EF2lYWEB/gun6KkTs/Z0LskAERk1XdcMwctH9Qj2UabrnstJAyGHbBFyywxEa64gkBbmI3VTtr/MQuXCmF3O3HYxxCOQF7fA+jbt4tZtTj94xOoWgafL9MDhwbDjyBmFhJeK02XC8QDB3UcB4YqpYLo4NOOFkgFrdjwO6XUqWhbiX+LyOrON7UEVA9Hq3v3VD5Dt7KTlpY2xuyMDLuNuXNZeuItJLZV4cZPdfJAZoy4ntVZBxMXaOC8zy+hsPZrOlpVp1cmUVA1B3fUz0o1mIGsRImAH8TppC0lm2B9K+EVdhpyh1M4MhmXCmn3xWAQMjPB4aAts4CStS48879g/p9ncO5l8d36MRj2fGJZM/Kh27b/jg5EnyulPkIHkndFxGO94BnAR8BjaG26g9EB7AbgRmve6Pfo4FaJnlMKAOlKqQ0ismwn1mcw7PU4/c2URvvRGvFwYMVH/G7DISxy7k9BeDVx0kaNLWvLuYHqBl5Jv5yckRlMbJmBOuJmOPBA2LQJVVJCQmUlAUc8C77ww8oVhCtqSEx14spIBpcXNX8D7c1hstpmMJQIi11jiVRUAWbwyrB76KqFxBL07uYxpVQ1cCa6AeHZTsHIi+6mu1FE7rWOFaD162ah60v3KaUC6N3ShcB/gcXoYDdURPyxXuBPodttxw2GDtrbYdo0ePJJ7Rv/619DcTEqORmAH/r/uDNLl8Jf/wqvvQYtLVuPDxkCpxwf4ozTogzZz23KQYaYEMs5Ix/wtYgcopQaBMwGegMT0LNGHcFoClpz7h50LWg5kAy8DVQDj1hGfFGgv4iUKaX2Q0sLfQp8LCI9KmVn5owMewLBumaor8fZ2oCSKOGEFBytjURdHvz9hmK3w9JlVm1pyBBwu4lW19LcZqem2YtNQqQ5W2jzpNHsc2ILB4lzR8lMaMPTywtOp25U8Hp1UFxTjoRCBFKziTjcRN1eEtPd3fwpGHoqsZwzcgODrLqRAs6zPIoA3FawAq3O3fH3InS904WWEXobeEUplYQOgGUAIrJQKfWNde3Qri6uOzC244YeSWsrwdTe+EIOXuE8AC5sfYp15NM3uJ4rV17ARTxBh1XbvOXLqXNmkR6q+vZ9wgpaOynOBqyfzVtPmZd5NCNr3qeWDFbTn0PrPgXgxrgHuGvt1bt0mYY9l1jajl+NDhTJaHvwALAWvQOahjbSy0UHqg3AOyJyr6WwcB+6L2cd8E90s8JaEUnd5jWuAfJE5NquLW/3Y1q7DT2VhvfmUp44gka/h3AYEksX0pZdzMEXFuNurMGXlElccw0A0/veyAH17/Lh0fdx8Ll9GWJbqW8ybhw89JB2HR05kmDUwatrRrH8uQVUlrYxxjeby/1/59P8c1l03t/oOzqNXN9qvMqPrU82gw7O6MZPwNCTiWWa7nDgf2jV7cesY6OA/ui03HEiMlMpFQd8AywRkZOtYDQZGAMcCqwC9gO+AA4VkTWdXuMZ4JOenKZLS0sbU1BQ0L1vyGAw7JBt7bpFttqLhEI6y9irl7YWcZuM4m4llmm6jmgV6XTMifYxaheRmQAi0q6UegesXEHnG4hsVkqVAtnoHdWDSqnTRMSnlDoC3aV3WRfeS7cRHx9v0nQGw26mvh5SkyN6yHbjRujbFxIS9JN+P5x6KuTno6xgNO+SS2h+42Nmfp3KPbXncf7+zUzuv5F1tXE8+tkwlpUM5sGLF3PecfW4vHa9E4xEoKwM7HbIyWFDtYv1lU6GH51L0oAsM9j7E4l1mm4YWo17DNrhdS26KeFoEcnudO5twPVo6aCT2bozOgZtzDcenea7Ffg5OsBVAVeJyJKuLq47MGk6g2H3UlkJb/e5lIvl8S3HwjYnywqO5dMR/8fE5f9iTMkLAFv09wTYoPLIkBo8BLa7Z9DuwRXpetNuU7/9SC7r0nep4TuIpQLD34E6tNNrK/Bv69h9QEQpNUpEFimlHGjzPWHrbupsYD1QjnZ0/RLd1PA3ESm2Unn3AM9aDRGLReQXXV7lLsZo0xkM3YfDAXGnT+WBmX2obomjypbDSFnEBWumMXLNawDcavsTJdFi4CwAznC8jOfsU/jLryrJLputh3nz8rT80dy5uBYuZLF3HPe/0pf15WE8+BEUaylAIRxUVMWUSSH69w2y/rN1HDLZ3o2fwL7FzrZ2ZwLPA5+jmxWuAx4UkUeUUmPQgaqviCRaX+QPolUbbkMHqgIgijbYGwYcTQ+2kTCt3QaD4XvpMMcKhXSqLy9P+3GwfR1r28saGnSnPOg6VkqKzhrubcSyZhRBt3BfIiKPW1/QC4ATgF7odNwj6CaFKHoHBdAPqLXawMvQDQy/EpEbrcd9d3pV3cigQYNMzchgMMCSJSw69mYibX6GN3yCKButrlTSAgFWNfXmnv1ncnj5vzgbHYw+sqfgOfYIHM8+RbChjbWqgJWbM0GiiNNNgmpjdTCfqoosBiVXktrHS3yCDVEKR3sLafWrafDmoCRKXLCRQMjGut89winX5HXrx9BVYmohAZwETFNKTUPXeOLRtZ8vgaOVUqvQit7fAEVKqeXW444phRvQig0XKKWeBwYA96MtJc5QSnXo3T0gIk915Y3vbmpra3/4JIPBsPcTCJDQtJFwRPFG9mVk+DZwQON7vJV0FlNrX+C6l8czKLSEs63TXXNn45r7IR8zibUUMMheygGpq+mVqvCoACoujsNLP8XW2kJTexqOFX4QQSH48VLuKCYvOouwctKoehHnEFoaI9/7FvdEupKmExFRlrTPV2h7iHRgIFpr7mxgCDAXWGH9vIVOyy0RkeuUUivRreBr0fWn/wJTgafpwWm6zpgGBoPB8J0EArouZbnp8txzqHPOAWDGfUvZvKyK9f0PZ+RImDRJi1l8i0hEp/r2wjxdLOeMOgejt9BacscDicBDaCvyZ9CNCMOAkcBw4Cq07E+jFYyqAYeIHKiUGgvcSw8PRmbOyGDoIdTUwIYNuquhqEj/6fNpP4yOwaGWFuaXlACd6jStreCNo7nNRmOjvgT0ZcnJkJTUDWvZx9gVtuMAdiAP3d7dcfNS4DcAlt5cOzowVW3j4FoFZCilJqN3V3sUZs7IYOgmvvoKOfhg5sZNoji0krRV37ZHeznv1zQm5HJxybVbWrzfb3XQlppH7qqXqbNlMjc6hl62JjI8rWQEN1LRlkVFTQ4Zzkb6uqtwuO1EvIkEcKGam3G1N9IqcTRFE7EhXNJ/Fg++kMHoLjnzGDoTy5oRli5dHLrpIB34BJ1qOxLd7t0bbSFuE5FKpVRvtNLCttyBtiT/XVde12AwGPB68e1/KI+lv0RjXZghdZ8SH2lmbcIwTqx6lFM3/A2fLY4v3JMgMAuA5lWV9OUr/qZ+w8TUVYxPrCK5IAV7QhrkTCBh/UYyS+tZ35TGm5uHIa1REmnBTQCfcyD29GQy49tIsrcRjir69beTmvq979LwE9mZNN3ZwFPo+pATrbRditanewYtknqBiDyvlHoaeEtEXrbuMQu4TkTmKaU+B14AThWRSbtkVTHCWEgYDD0cnw9Gj4bVq2HxYtRQrbf85Swf8ZvX03fKABITv/8WkQisX69LNqmpkJZmRBdiSUxrRsAhwHTALyIDrOPL0B1zvwZeRLdub0CrLTyI9izyisi0bYLRMWgDvjU9PRh1Jj09XUzNyGDYN9hO6y4SpaLSRnU12GxaOSgU0uWqwkKIN4a430msa0avo7vm7u107FPgcuB24G/Au8Ai4Gu0i+uh6G67byEi7yil9og+6W0VGEzNyGDYc6mpgT/dGuKcpTfQy1+FXUJE3PHYJcyKw6+iccABDPvsUYa8+ic6etrmHncCTa/Poteij/iCCXgLsxjhLsGWmkxjs43ZZTnIqgCHpC4hORlUOKxt3P1+aG1FsrJoUUk0h+NpdGXS98BcEi87Gw45pFs/i91JLLXpBO1HVCYiv7KODQTeQ6frmtGGe5nooddCIB9oAkJob6NkEWn9USvpRkyazmDYe/jmG5g8SVjdmE4jKYRwEkc7CbSSSAtlFDGIVayhkCLKAa1rtoJBfB53JGclvEm8O6zTgi0tEI0SWbue6lobn7SNJamXneKBDhLTXLSEPJRVxdO0shJnsJVEWsm2VzM4cSPO++6GCy/s3g9jNxLrNF088AG6DnSnUuo9oB6Yb3kXDUcrbw8XkSs6akboYdlyEbnlpy2n+zFzRgbD3oHfr0eCQiFdL4rWN5Byx3XYaqppGH80Kyb9kiN/pjXpbv1NC0UjEzj1VN0OviNE4KWX4Pe/h9LSrccTE+H44+Gss+DII7Vh7pYL9qGi1K6YM0oFPkMrJ/wKbS2+2gpGCt3EsEhE7rOCURNapftAEQn/tOV0D0qpZ9FyR8THx8cZbbrdSFMTRKPMX6Ntr8YMGQLBIIGIg6paO8HWABG7G1eSh1BIj5MoID0DsrM7/Y8fCGghMLsleOly6aS/wWDYLXS1ZtTlYGT9PQ9dK3oTK32FlvxpRteLLrQ8il5G74pq0Np2G0Rkwo9dTE/A7Ixiy/ST/sv4mbcTZ/NTl9iPypTBVKSPoKTPYZw47xbGlU4Hvm0NsEO8XvD7icYnIO0+AlEnbcSTxmZsO7hKlKLBk01TXDaFG2fvlRPvBkNPIpYWEm1KqVzgYXRbdxT93XABcDfajjwbPRA7Rym1BO1ndDEwCjgVONB6UwXo+lK+iEQ7vdlFwKUiMreL69stGAuJXYc3M4mKuP40+10U1q3iwKrPiZc2AII4ucd7K0PDiyD0BgB/9NzF+uLDOGJkLcdNqCNhRD9YvBjWrAGvF1trK3i9BKqDfPNpG1+WZSA2O8lDc8kYnoUr2ELpyghtS9dQFFzH/nmbEZebfSdZYjD0bLqyM2oFlgOPishTSik7eraoXkR+a53TBlwmIs8ppf6AlgU6A61Ftwm4QURmWefOsR5/Yj0eBLwtIkW7YH0xw+yMdjEiMHs2zJgB554LgwdDKIRyuaynv//f6basXg2PPgqvv67jFUBxsb715ZdD796xXoDBYNgRsawZbfEz6nTsZOBxtDRQErAOrVfXhB5oHW39XAu8BEwUkcusa68GBovIL63Ht6E163pck4OpGRm6m2ibj5DNjcNl267mrdrbUeVlEAxaZgUwprgYysqQuHiqbdnUtHhItTfj6JVIxOakvh6CYRt5WSEycxxbC+nhsDbXcTq3qngGAviCdryJO6saZjBsJZY1oyjapbXJOnQ/kAtcgQ5CfrR768+BP6NTc5XoQNVqXZcJ5IlISCmVBSy0HoeVUiuA00Rk6U6vcjdidkaG3U4oRDQ+gWgownscxb1cxy95lKN5l2UMJZManIQoV0UcqhMNBGxuKr39cLU1kE3VDm/rt8fjibTht3lxJHpxNNV/6/lISiqt0TiSmzfySx7h16t+yYABu3y1hr2UWNaMQEv9NKLtIR4TkXal1K/ZajGeB5wHtKMDUQLaeK8CXWNaidaxe1tEqiz1hsOVUtVAqKcGIlMzMnQrIjQ+/DybXp/LkTMf4tjQO/g9KZQMO42Ry17DHWjm3xd8QqWtDzxeCMAK5wiu6juD/Q+N46bi/5Detg6OPho++0wPYwaDuGtqmVNXzIJXy7E3+XH1ySA+O4mS+P3wrywnt3o+KTRSP2ACR172M/r06ebPwbBPsLO249OB+WhTvCYg3gpMs7DkfqxrbkIrM2y0bhMHzBSRc63nL0LPJVUDTSJyV8xXFgOM7bjBYOgJfJ+FOejfM3w+XXp1ub57Jqo7iLXteJxS6hfoOaORwH3oHU37d1xzOLBYREYDKKXigXKlVJx1zSvAneid1GFdeA/djrEdNxgMMScaZemLS4lfOJukVV/jaKyl+YhTSH39KQIFA6m8/XHi16+g8JghAMw780wtJfTEEwSaAyyvzWDWqiwWb0zFj4coNlpIpDkpjxMnVDNpnI/hg4K4w+162reiQkeshASiDidrXQOxjR1Nwbhd19ETazmg5ehUXBw6XfcCumZUAvRBp+XqgFnA9cAydB1pGdr3qAZtU/4M4EX7Hbmsn5tE5G87s7juwNSMDAZDzAmHaXGlkigtVJNJEBd5bCSIExchnuMczmX6dvN27bZ46qKpZFKDh0CXXy6K2m7+7t0Jt3P0F9vJiMaMWNeMQsAawA28ICK3K6UusK4/R0TetF50Mjow3QzcKCKjrON3AUEReUkpdT7wkohcpZRKA1YppV4WkQ07ucZdjqkZGQyGXYrDwbr7X6UuuYimXgVIKMzaJbNozh3CIX88nHM3TWfd2JNh3qsAXHPYYgrWfcLcgtMpmpDJSScKo4uaoKFBq42IQH09bNxIIDWL+Svimb/ExbLyOCrq3FRJb9xxdrKSfeT39nNk7gpGT+0ZRcGdVWC4HBhh6c/5gf+IyC92cM016GDU25IKeggoFZG/W8Foi9W4UupL4OqeNvAKpmZkMOzLbFenCQZpaFSs2+QkEtl6XkoK5Od3kqAyfIuY245bw66HA09Yh2ywZbxhR6Raygpp6Nbwm3Zwz3zAAyzu6vvYnYjINPSAr0nTGQx7EZ/84SOy33+G9Mol1BfvT9aS92kYNJFl1/+blKQow5++lgQrGM2bNo3m2Ytx/+YKghE7i1MnM84/C8nJpWVzgI2NCcxfNYGf5S+n94BkbMlJuosgJwdKSwm4k2iOyyLU4ifoTqTWn4hj6AD2u/nYbv4Udg+xrhlVoWeF2oEy4DK0UGoVWgpoIzBdRG6wrqkHEkTEZT3+HfBb6/x7gb+j5YO8wCUi8tROrm+3YCwkDIa9k89SjmNE06csYTgHMJdVDGQ4S7mXa4li43ru2a5OM4cJpBenUNw8H3XssTod5vXSvnojauECFkZHkuxoI9XdhjvqI8VXyTpbIQnRZtLYTAA3XvwAzMs5jrEVb3TL2nc3sawZ+dCyPiOAV4F30I6ul1g/ZUCkIxBZBAGfUirPqgUtRdeSOvgY7YX0Z+BtpdS7IrLjCb1uZNudUTe/HYPBECNGzXmUJkcaGVEvpWGBCGy+9SKue/0+AJaPvwC+1L8j3zj4NfoUeznyz4fSf7h7u3vFoUs1dW/C/c/AsmW6fJOXE2HgEDsDBkBuHyE5ReG2hchPbWVEbnS7++zrdHXO6AMROU4ptR/a9bUIHcjq0em3K9HOrsPRg67vo7vu/mVZTLxpXRNF74xOAJwiMlUp9QDQLiI37ooF/hQ674zS0tLGGNtxwz5DKAQbN2o/7fT0Hdpu7Miau7rWRlUVRCOC3SaEozbshMlOaCU9Q2FPSdx6L59Pv47Hs1WWyNFJCYrNjQAAIABJREFUosiwVxDrOaM8pVQJ2mBvA3Amuo27GjgKSEXXj2ahvY5At3z/USn1c3QgOg3d0r0tdwMLlFJ3ikhLF95PtxAfH2/mjAz7BDcd+w2//XQqye1N2OrraWkMs2DClTRkDKRs2Alk1S1lxKJnGGGVjB8bfxWZr00jv2IOURR1njzS7dUohMiwUdgWLsTWGoVWbeFBYSEqENAzL9vQ5kzGf8wppP3rbh0EDXs8Xa0Z/WAwEpEEpdQtwEXAKejA8yFwG5AI5KDVGOKAy0WkUSmVgtaqOx94Fi2iOgHIFpGnlVJrgeus+29CW04YDIZuxu+H+iUVtLTZmCzzSKaJO1pu4dCZWsd4FocyhvnY2dpONvbhCyingOeKbmXieKGflEFWFoRCOL78Em68gdX9j+GvfwrQZ82njN+8koxcNw1jx7IuYRhSUkJtZYSKTYrx0a848YuPICmpuz4CQzfRlTTdBLQ46iQRCVjzRWehg4sP3dQAeih2vogcoJSqA2YCM4C/oYPS7UCyiPRTSk1CywdNjf2Sdg2mm86wLyE+PxGnh0hE10Nkcz32l1/C+esriRYWUf3SJ/TZX8+nLH1pKXlTBpHUy/699wyH4amn4Omn4auvtOW3zabbogcOhNGj4f/+D7J7R40b715ELC0krgJOFpHDrMd3AGPQNaJDOunR3Q78HzAJ7QQbBwxEm+y9ik7hNYjIsD0lGBkLCYPB8H1EozpY2yNBaG3VNhxxcXpn19AAaWk6sIowf4HOVo0ZMwbaffgr6/G3hGiOxGG3gcsRwRd2EY4qcHvIzHaQ4A1/u44WjeqobrMhkShRbNjj3D06eMeyZrQIuFspFQBa0NJAi4Gh25z3MnANMAjdqLAAOEhE7lZK3QC8heX4anG4Umpjp8enicicLryf3YaI/BydbjQ7I4PBsB2vvQbvn/QwD3MVAGHsOIjQQgKJtHJ/xRm02pP4TehuEq1rZi0uIy7URBQbjfY00tmgvzGDnW4cQPcwd5Wmph6b2oxlzWi2JedzEXq3MwG9y0kCXlZKNVqn3oFu2f63iHgsFYZXLBvywUApVgOD5frq3ZkFdQdGDshgMHwfQ4ZA3XVH8NIXD7As/VAqUwZz/LK7GFg1i/XuRK4pvw9bJMqCvONhg54rmplwCtHe2Tiv/zXHntsL1q/Ru6nkZN3UEQoR/Gohcz728fYXqTSsacAuIQDEE0dC3zQG5LWTkh1Hgq2dIwasw91DA9HO8FNqRgcA/yciz1rn2YHVQJaIxCmlhqB3UAeghVWPRqfrHuipQ67fh9kZGQyGnaK2FoYNg3Hj4NVXUZZe0A99526Lz6c3Pm63lh7a0zrfYzn0OgbwiUiHNGwRWq37gE4v1jHAugGt1AC6saENeBItrrpGKfUbtP3EHhGMtqkZMXbsD36eBoOhBxIKQVNtkPhgA46QDxUKIA4XAM6WeoKpWQQz+uAI+1lWtgywLNztdsKVtQR9EZpDXiLY8DqjYLcRCCl8ERd2uyI1PkhcgsLusCJFJLKlthOeu4D29CLG5OVBWtq++D0yuisndWVndBDwHjpwddSMTkan3eLQc0gKeA7drr3RagcvAD4B8oHBIrLSavmuFJEen6IDIwdkMOwtvP8+3H3kB3zAFKrJpJRiRvINCbRRRW+chHiJM7iCR78lAxRFUU8qtbbeDKAEe9RqKAiHf/A1AzYPKhrF1bkYtGYNFBbukjX2VGLWTWfdrGPOKA49Z3QXcBJa0idg/fmAiPxTKRUEatGzR/2A00XkDes+vYDNaAuJs37MwroLk6YzGPZcRKB2g59NK5pojddGco76GuJKFxN1uhl19SEAlE65nP7vPwbAf0fcTjKNVP/yj0w9M4EUj193s8XFaWvVQADWroVQiJJwP978X5il8wOsr7DTHE3AnZZAbi6MHdzGWce10idX6e46+/e3wO9txLK1e0c1o3OAg4GTROQdpZQbKBCRVVYwugndXfc+0AvIFJGoZR/xKFpGaICItP34Je56jBxQjPD5dNoiIeFbh3dkpRwKwYYN0Nhotcza9fxk7957Xq7cYDDEtrV7RzWjcuAQ9O4H67lVO7g2AISBdKVUHHpH9Sa6lnQ8urFhj8DIAXWd+gofjZ8twfvNlyS/PZ245cv18TN+SePtD9Ln1YdwL1uA6pDonzkTHn6YylfnMHXtgyxumUw0M5vyoy7nf2UjeOTzEZxom8Glf8hmxPEF8NhjMGCA1jRLSoJRo/C99Dprm1JpT8sjPc9L/pSBKJuJXgZDdxNLC4nvqhktQTu/voeeIXoB7XHUDNyK3hmtRFtFlFrX5gPj0MOwV4nI8Tu5rm7DpOm6zicn3Mehb1wHwGKG8yQX0ocKfsu9/IfTOJlXcRDZkpuP2OzYolpexm/z4nKBLau3ToEAUbsDWyRMCAdNnt6k+7+tabatlXIUBeEINrsJRgZDdxOTbjrLFvwf6JbtfMCFnjNagNaTW4XeIZ0A/Aa4EB18rgfORYun1qLVvJPRNhJHojvsnlRK9RKRhh+xvt2CmTP6ceRdeQKfFxfS2G8/2jMKONDKr5U+3sbp7z9KW3wGv5/yKbw2GIB/Ri+hNnUQBx0Eh71xDTw4DS68EEpLYeFCbF9+iX/0RMrvepG0ki84iM8I4iKKjVEJZfwsfR5NU05l4IAoiW3VtDUGmWgCkcGwR9GlBgYApdRtQCt6Lvg8YLKIJFjPpaMN9tagGxxeFJFrlFIvWsduQVtHnG/drtk67zci8q8YrSXmGDkgwz5JSws0N+tCfW2ttpHoo3XotqvzWee1Bx1UVW2t9SkFSfER+ngb8Ob0Ase+VbQ3bCVmNSOl1EC0WEUHo9DWEfZtjpVaunNrreuK0LNIZ1vnnAYMF5EK6/nJ6CDVY4ORkQMy7EuUpowhqb2KzNCmLceiKCJtAe4sfparFl1Eh6nDnI1V+I+YSuL0f7LZk8OH/gPZ3zYfT4qbuhGH80XWyYx67Q+Ma11E0+YmaosnkJCViD3kw7ZhPbaGOpY5RrHQN4iJwY9JdPhYecy1HP/6Rd2zeMMuIyZyQFaa7g0gFy3fI+jaTwXgUUp1BCkB/mn9PRfwoLXrvkGn8e6yrpmilHoKOAItKTREKXUh8ARam+7lLq5vt2DSdIZ9icY+wyhrHsUyxyjeTT2H/q0Labcl8PTK8dz4+bG0bFFXg43VTgqn/5OXOYXhoeUcGzcL11GTcQbbyP7wXwz3/wOAhWfeTc3MRaSXrCJcsoYAbtaTT6tzJEeF3mNC+D3W9j2EzaoIb57xL9qX2Zk03SygxXJ8nQDMBuKsdu90wCUim5RSfuBYIB64AHgAPQw7B7gMyEbr111s3fcldEPDHT0tGHXG7IwM+yxHHQUzZ8L06ahzzgHgv4/UkPr1e9jOPpNxBzrwemRr731rK7zzjtavOeEEAKqroaREd/jn50NBAdgiIT2rs03Lv2HvIqZDr9YNZ7E1GJ0M/EdEtttZdQpG69CeRhcB11oW4+cD09BddmPQ3XifoDvz3uppwcjUjAwGw3a0t0NNjVZiSE/XA7A1NdC3L1j6c9vV1qJRaGmhzZ5MbZ0utUWj4HJBr176Ntalex2xnDPaETMB1cmK/CUR+aTzCSJSqpSahw5GHTjR0kEfoO3Kk9FpwB6pj2FqRgaD4Vs8/DDhq39NQHlwRZsJ17VikwjuqJ+Vaz38/uBZXFp+I0daluyziKd14lHY33qdjPJSFjKKBFs7cfE2WpNzyK38ms83jSdQ5aU4rYGULA/xqh1/QgaBumbs1ZvYJNk0Bry4w20E3Mm8c9nr3H9/N38OO0HMLCQsjbm3gLpOh69DB5UstIL3JUqpmSJyrPX8B0qpq9HGes8BR1mNDUHgC+BF4Gp0MLoWrdjQ4zA1I4PB8C2yslg18AR+n/EYkfYAt5ecQXy4mf/mXM3vSi/hto8OZrBv63fv8vk+Dph/M37cPJxyM2e7/kvi8AIcThts2gRTTmXSrC+oa3Kwpj6dxtoWfHjpTQk+vFS6hlDgraY4sZmwO56NrjRSUrpx/buQrgy9FqCD0ctAq4jc26nNe5j1HMB5VgpvMZADNAJDgKloRe+7rfPGishVSqlFaGWHCUqpp+mBabrOmJ2RwWDYIVHLJn36dDjvPMjJQW3YAMDLLwue9SUMKIpQNHXw9xqyBoOwcqW2NIqLg+JiyMnZ82WwYmkhsSPS0B1zHYxC14gAvgROBD5EzxX9DD2DtC03Av4f+fq7BWMhYdirWL8egkHmNzUBMGbYMGhqIhiE8pZ0fO1R7HaF3WXH59Nfgrl9hMxMtv9GDIW05mBCQo+2vN7tjBoFwJhM7aRz112dvjNu74431CPokoXEjw1GLuA4IAWYjFZauNR67iHgdHRL93nW4+0sI0Tk3R/52rsNUzMy7Ek8M/U/HDrzZpanHsTmuFz6tq8gIdzE2/m/ZFDTV5xa+1eALTJMX5Suw+VvAaBBtdKLBm0IIx7CvVPZ4Eun98bVuCuCkJ2DPS1Fq05XVsIqLUUZjU+g3ptLe1sUDwEy28r3/F/lDTElZjUj9GBqmojcZt34PSADHWSGo5UUZgOpSqln0Kk5D7pDbgm6TnQqME9Engae3vYFROT8rrzZ3Y2pGRn2JFIHpFO9YCjj6t4hpbqWOmcOguKWhacA8FbS2TQG48Cv58zX+Xtzce+vOX9KBee2Pgr7DddqC1VVODZvpqCmhsVtk5jxWQJ9qisY4W4kJ1RHOHUIpceez3sVw8he9C7pbbWkpNrone8hMxLRXWYGw07SlX81n2CpKCilbEA6elaoo6FhINq99W20Pt0SdB3pUbQW3YNs/WXMYDDsIqbefxjcf5h+EImQabPpQsQnn0BWFlOHD4dIhJ87dTBKmP8ps/bLRousHLbd/RQwEohbDbffDhe+pLNzHRQVwZk3T+Xoi/Y5vzjDLqArwehDwKGUOhyoQVuODwIWA4ejFRcGAnNE5E2r4QER+RjAshofH/N3vptpa2szNSPDnkkwqOs61o6lY/bluEumAjB/wYKtx8NhwsEI66vcNDYILocQl2gjENCByOUU8vMguZf+/XLGG0FmPNOo752a2g2LM+wBxKZmZKkq1AJ/AvKswzPRu6N0dP3oPiCilJqDbvXuzHPApK69556L8TMy7HE8+SS1v72bjPoSADb1GcvsybdSNuBoPIEmzntsAjYi9LJOfy2YSfbSmdglQg0ZZFKr3cgkBSaMoTaYRMLs9/CuaafB3Rv34CLili7QyqgATU1gs+FPzqQqkkE5/fjy0ie58cZuWb2hhxArbToFfIa2ipgGHA0sBc4AJqJ3Sg502/ciEXmgY2fUiUFole7Xu/72DQbDT8bnY7M3j4dTrqC9McAVFY9w+nPHU0kWzSQRzzo2krvl9NCSFdxvu47eo3M4Pm8h7FcIXq+28li0iIyaMqIXnsNnFQVUfrCMokUr+SbvVuqPOot+bUvovXAGGyoduMpqSGMzkbjNNDd34/oNexRdmTMahlZMeAU4EK05dwZwDzo914Q2z2sSkV90zCVZCt4/B25DK3oftYvWsMswtuMGw25ARLeJR6PavddKJ24nqRMIgNNFIKTw+/VlHo/+MfRcYiYHJCJLlVIz0Om3ZuAJEVmglEpFp+pOAZ4B7EqpY4FlAEqpP6OD1m/Rpnt7NCZNZzDEhoBfmDXhBvKrvyaraRXJvipsog0ANqaN4OnT3+CcD86nn3X+9IMuQpYtY9AHD7PCMZznw6cxmgUEceEgzMqUCeRMHshU339IHZKNPdBOML4Xa+OH4p8xi6p6F03NCn/ITl1cPkPi15J/4RQGX3fsd79JQ8yIme24dbNEtKLCZiDPUur+FBghIilKqS/Q5nmXondL+UAIbTHeC7hORKb+qJV0I9u0do9Zt27dD1xhMBh+iEAA1sQPJ2Dzsso5jApbHssdwykKreLGtltYpQZSLKtxWDZqHd9QLzrO4RjbDJKCm/H1Hajv5RdSqnVNbDOpJNJCG/Ek0oKDCE0koRTYbAonQdwRH+0qjrKzb2X4c7/rjuXvc8RUtVspdRLwKnCviPzWavEus55uBZKA90TkUitNNxvoA/xTRC7vdJ/WDnfYPQ0z9GowxJAOCZ3ORCIwZAiUlBC87ibc994JwOf/rSA1FfofmoO9rVlbVOTkbL3u889pXbGBGfEns3iZg9Z2G3meWkYnlDDg3APIzndufc26OkhPR5TNzObuJmIdjP6D3uWsEpEjlVKXAI+hZX4E3VEXQe+I+gJfo4PVYOAKEZlu3WePCkamZmTY19mubgNs3qz10zpmjpTSNgi5uXuvDYLhxxNL2/EEdOPCq+gaEMCRwAoRGdbpvE+Ag4ANaDXuc9AK3XcqpepE5L2dXkUPwtSMDHsbm8ubUcuWkhyqxV6QDyNHfnu3sngxauRIAObNm8eyD6v44tKnmbU2j+QhuVw5dBYyeAgfLe/NvW8MpLy8Nw/9eg2/WPY7VHMTjB4NxxwDbW2QnAyZmZCRQdCbTOPaRsLN7eSMzfmOd2fYW4hZzUgpdS5a8PRwYBNak+5fwAh0m/eHQBva1bUJ3W3XFwighVDb0fJAxwCfAuvRu6kK4CoRWbZTK+smTJrOsLdRmzZwywwSwHryeFD9imnOqzjX/gKP+C7YIp2ywjWc4uByHER2eC+x21nvGUhWWykhmxt/34GkbViECoe/dV4URSn96UcZLyZdyrlNj+yq5Rl6CLFU7T4LbYo3G10fOgutZP02Wnn7KrRR3mki8j+l1MPo3dG5aJ+in4vIaUqpqwA7MFJE2pVSRwJvKKWGikiPVO822nSGvZmm393J3DUuKiJZpNauYr/FT3Nv+XXcKbdi9wcoyTgQaj8HoD2lDwv2O4H+f/w5verLdK5u6lRYswY2b0Z9/DH5ixdTYjuGy5dfzayyPNKo4zDvl2zyp5IkjaSxmYNy1nCw52sW9T+N3pNO6uZPwNCT+N6dkVIqDV0XcgJVQG+gEq3I/RZaFP0P6KHXVOAa9I4nilZnqETbTWQDy4FUEYnvdP9ngVki8kSsFxYLjO24wbAPEgrB6tWQlKQLYd/BjuppItqV3G/9eu3xaG+ifblZIlY1o1OBOUC5iFxktXC70c0MBcA/0LpDd6K16o4AvgEuY+vg67+BM9Hpu20j3zxgaFcXtbsxFhIGw77FuhXtuI48lN6BILbqajZ4B7C+aDJBbzIrR59NoFcWRWve5/BnfkHHb9WPnnwX4S/nsd87d/A/dTLfhIcykm9YTz4e/DQ6MxlUGGCcayHJqTbilB+lIBIMI7V1NPUZSkN8Lu1RDy0qiTH/uICkwrRu/RxiSUxqRkqpWcCh6M64NvTupxotjprZ6dQ2YA3aWuJh4PfowLMWnZoLoFu9BW0zfg96B5UBNIpIjwxIZs7IYNi3WHTHWwz9/UmcwisUUs5l/JMhrACgmkzu41qu568k0oKHILD1N+yvXRMZHZqLXcKEcvJx1FYSdnhw+lqIYGM5QwjjIIAbQRHFRiMpjOQbUqnHgx8bwpr3y+h3RL/veId7HjFp7bbSdHVsbTqIBxLRLdtvoo31SoGnReRX1jUFwHtAyNoZ9UN34hWig9Pf2Go9/gzwSQ9O05lgZDDsQ4TDECxZiyosQCmddosGw6iVK3BffC72pYuJJqew/vnPKTxW/w69+OFPSe8bT9Yxo1Fry/W8VHHx1pu2tCCRKOX1yXzzDVRV6deJi9NehRkZ+s/kxCjJzna8qV6Uw94t698VxCoYXQb8Q0Sc1uPT0D5FJwGPWsHmZfTu6VwReW/bYGRd9zd0o8N84Am0TcpraPHVoSLi+7EL3V2kp6dLTOeMamq0HpfLpVte7d/9jy8Q0P+AG+p0J5Pdpc8NBnUuOj1dzwAaTzODwdDTiFXN6CzAppRahG7PzkYHkJs6ndMK/AV4Uil1MjqNty1/BC4H3gXuQDc1nI9ujjgTeOqH3mh3sG03XUxqRjU1rBhzLoM3zseXkI5ncyWhxnZWnngDzUX7EU5Oo6l4DIHaZnKfvYu0RR8Q31yJBz/pbLZuogNYSOxU+VNYVptNU3MGo8coivsJKhTUgc7ng4YGxGanxpPPEn8xiZWrqb/0Bo6+Zcz3vk2DwWCIBTGxkBCRSUqpVqAYGAaUo4NIpoiIUiod+AVaCqiPUuo2dOddR4ruOuBidHed27r+d1hpuh+1sj0csdlJqF/HFY5pPNp6MSNYzJ3tN3Hs8zdsOWcZQ+hDBUk0M9c7idYRwxk0yg3D+untT1UV1NTgjETIa2wkrWwTTWUr8H+hqPga4nu5cCV6CDq8VAfSqaqMUhj4ism8wnpnERXra7vxEzAYDIbt2dnEzhq05E8G2svoNLSA6nYopS4HpgAHAGOB+zH246j0NPIal/J3cXJDFYRCIwmF3qZs6UKkuQX38oXkzX6LSP6BtP/yYsZPPuAH7xkHeKLw4otw112wdCn6vw5anuXII+GCCyDzyDCFiQ6MQ7TBYOhpdEWBodX66zC0w2s+cIiIzLW67RKBGhE5utPO6AS0eOpktGbdq8BDIvKUUup89pCdUec0XXx8/BgzZ2QwGH4SPp8ePvqewaNvzS+JEAxBS4vC59O9EQ6Hbn5ISNgztABjpk0HeK0/30Hbjv8VOF0ptQkdaHbUfFCEDkpvAS1Ygagrb7wnISLT0DUyM2dkMBh+NGX3vErSTVeSEa6iytOXRb0OA4myJOlA5vU6kv0b3+eApvdxOoWJ6GD0n3LoV7+ACDbmcgAuFaKQckRgOUMopZjUpDCF8bXYeyUR6JVFOALhFj8t7XZa2hTh1gCZoQoK1VqCC5cxcMju79KLSc3oOwigh1rHAC8AQWCyUmoN8B906q4OiBeRwdabeU0p9ZCl2D0LeEoptUpEHrKe/wcwT0Se/hHvZ5dh5IAMBkMskJw+lPY+kOneyUypepaxdTOwEeFnVf/ecs4mV1/iwlt92v0tYV4ovoV++WFG1s3Cm56MGnQmkVCUUV8tYdTa9/n/9s48vKoiW/S/OicjhDmEhFlkUEImghpuN6OaqMGoKI088DOIPBVQ2jRBeW1/wGu1tdurtBMi3baIevGCLQ9bRIabIFzSXhMM8xyBhowmJGROzjnr/VE7MYSEJJhR6vd9+zt711m7dlXtffY6VbVqrZJKNzJ+8MMz43v68xWCokx5425zYrcJLndPCrv14YzXaEa4FaF9WLdPGqOMqno+d6G9KryglBqO9sq9BLgBGIde6DrMkr0AeFhrjPLQVng1yQYWKqVWiUjFT6yDwWAwtGuGzryFoTM3MBaA+TpRBA4fhi1bYORI+t5xhzZOsmI1jSz/jpF1DOfZ0XMjWJ990B6MysrA0xO6e1wq3xPtubq9c7UrU/6I7v38AdgLuIvIR9acEcA6dJiJt9CLY/8OBFo9ja1ADvDfwMPA6qsufSuSm5vLmDENrtu6jKopOeVyQnq6Xl8E2qV+jYVxtf1cVVRo8dxcvQSpRw89VlxUpDe7Hfz99RKlS2KUOZ2Qn68Te/TAVV6JzbMDDCwbDNc6v/sd8OM7YMxNN7VlaZqT0Y0RauyckaDnjK5TSk0XkU+A3yilPgXmAptqnbMDvX7oI7Trn3NWPiU1ZF4CvlRKvdeYgrYFzTFntG4d3D2jM52tqq/zXUCZvTOxWS+zM20APSSXN8f9JykpuvP4uvet3JC8lrcqHyPG+Rk3uJ/EvZ8fNkSbxe3ahSM9i896zqH8+3TkB2+GD3EwyDsL74oCuhz+BptLL459yXMpc8vfoNsLi3H7PybEssFgaH2aM56RALki4msdu6G9cX+DNtdehQ4v/or1fSIwHNgCbAfWiojdssr7Fbq3VCEiIyx3QBPRcY9ebOdzRlflDmjfPsh8+mWyc20c7TyGA76TcKss5Z3EG+henolL2XHgRhdXIaC1/jG3kYxwHMYR0B+3B+6DvDztCviLL2DwYBg4ELZvp7x3P4ovOiktt5FBACV0Yje/ZIstmne8n2Zk8bfk9RqG984teAf+fHxdGQyGjkNzuQN6HO3+5xQQJCKlSqk70cNz54BX0D2Hd+tQRo8B7wM+IuKplCpFB+ebDbxtLYq9Cz2E5wDirJ5Iu8GEkDAYmoAIuFx6fNnbW/upsqgr3AKAo8JFcXoB2RXdcTgVHh56BLtnz1rDz4YOS7OYdovIO0qplWgruWh03KIZaCu6cQ3knYRWWsuUUuPQHhii0b2gKsYCx9Cm4GENFba1MSEkDIYr43LB32/6A+NO/Y3eBScp9+iCd4W2CNvdOYrtt73EE5/eir8lnxwdDTNmcPGVd9mUdQuVW3Yw27Ga0x7D+KHrEE6UDeCbM4HM+9cqSq8PpPuEUPoM9sLDVUZFQRl5F+1cOFdCcUYBhaVuuEklAfdGMPzlOW3XCIYr0tzDdMcAf+CM9TkdWMSVe0bBIvKDUqoSvdbIS0Q6WY5Uq2IdHQeeQs9H7RORdqWQjNdug+HKlJXB1z3uwdtZyP/YIujvOsvfvOZxt+PvzC/9d5LVGMJkL264AHBgw27tV1Fw+wN0yzkJSiFHj6JKSznVIxzPC5n053y1nAuFDaEMT/LpjrvNiQN38iN/xYgvV7RqvQ2Np1mG6ayMitC9g7+jHaR2QQfS+8j67I82//6diKxRSgUCqcBgETmvlCpBK6O9wCf8GMvIGx3j6Ga0sjuDHgq80PTqtjymZ2Qw1IPDcbnLeIcDIiIgJYXSR+bT6b23APjdA4cJO/4JFyfczf3n/4xP5inYsUN7JQBt2pyWBmPHkndB8fX2Ck4fK6eg3AufHu5cN1i48UYYNlwZL/UdhOZWRpvR0V17W5+B6N5QV6XUAnR8o18Af7Zc/pQCr4rIb639/0a7UEsHMq1YRq+iTbsLrUv1RM8b/eUq6tsimDmjZqK8HM6cgcJCa205hI8YAVlZek2FtzclJVqKGYkrAAAS1ElEQVSkxLK3tNm02XpAgJk7MBg6Ms3pDgi0onkQ2CAiB6zeTxVfo40VngWeV0oVoC3tHlBKrUfPFT0B5AIHgKNKKRvaU0OwiJwHUEpNAp4D2o0yMnNGjcdxsYRdYU/S+zcPM2reeEhOhnnztIfWFSv0wqiuXVEX9XxCcn6+Xg9VWsrJ8Y9w5Lt0+tvTyZvzNNfnJJH5XSan/uWOlPZg7NQAru+SrZ1x9eoFBw7gdPck81AeR8/58GXhL4nquge/+FhC5v+yjVvCYDDUpLFzRojIFTe0wcFfrf096AVMDwIXa8g8hlY0LvSi1iHA3cBFtBl3lVwc2p9dGjpUeSrgbX1nR5uMBzRUptba0PNFyUDywIEDxVA/5w4XSJr7MDlPgHz8b29IuXsncdjcRECcNrt89vROOXhXvKCt18Xp5S1H3/kv+XrYbCnFU/LdeopjwGAREPHyErnxRikOGCL5tu4iIMW2ztX5XfD2lyzlJ8cYJgWqqwhIga2bfLfwb23dDAaDoRZoV28Nv28bFIAvgNut/afQcz6DgYO15HoApbXSzqJjH1Udx6Ijx7a5omnqFh4e/hNux7VB/u79Umb3FgHZrX4p/TkrL7FYHuZvAiLXcapaGUWyRUDEbhdZGndRygtKRYqKRDZuFPnhh+o8S0pEVrxYLEOvd4kXJdKHDOnaVeTBB0U2bRKpuFgqsm+fSGWluFxtWHmDwVAnjVVGDa0z6oVeT5RtvUTs1ucE4HOxwopbspOBV0RkdI200+hwET9Yx7F0kPAR0LHnjESgPKcQ1a3LJXMuSgHl5bidOgYOBynW/Q/394eKCqSXL/mVPlSez+JipTcFdMNm0ya8oNeABARA5851XNThqA6fXppTjFdvnyt5yjcYDNcAzTVn9ADwgYg8VpWglNqJtqCjRtpgtJn3G00uaTtGOvCcUd4rf6Vn/KNE/WsLO5nADP6DsSRRhA+P8B4OutKDC7ihlVFyZialyhvvvOOU4E0nyz9u5YRbcTt6EIdHJzJc/qRkD6D8qCLSLQFnr974UIxHfhZOD288CvO46O1HRQX0dOawOf4UU540ofwMhmuZ5gohMQPtQ64mn6JNvK9XSn0HeNG0mEXTlVI1Z5nniciexhS2tenIISS85syiaMUf2VD+OC6bG92yT1Lu1RXPsoukBcWw+55XuGnzctj7EQAbgv8vnw1dxF0lnzLZsRXP+Q9g37QR98REiIrC3eFgYGYm/T33UpJbQgKRSFYBJXTiPP3wKS/iJEO5pTIF3x5OKmfGMunhjtVmBoOh7WjQtPtapsMvek1IgMmToV8/+MtfICpKuwP39NTfnz6Nuk73XK7mOcjMhOPHtTl29+7aZZ6/vzHFNhgMP9Js64wMGqVUDnph7rXEdcD3bV2INuRarz+YNjD1/+n1HyQivRsSMsrIUC9KqeTG/KP5uXKt1x9MG5j6t179zYCKwWAwGNoco4wMBoPB0OYYZWS4Eu0qvlQbcK3XH0wbmPq3EmbOyGAwGAxtjukZGQwGg6HNMcrIcBlKqTuUUseUUieVUs+2dXlaCqXUe0qpbKXUwRppPZVS25RSJ6zPHla6Ukq9brXJfqXU6Ppz7hgopQYopRKUUkeUUoeUUgut9GuiDZRSXkqp/1FK7bPqv9xKv04p9Y1V/0+UUh5Wuqd1fNL6fnBblr85UUrZlVLfKaX+YR23ehsYZWS4BKWUHXgLuBMYCcxQSo1s21K1GO8Dd9RKexbYISLDgB3WMej2GGZt/xtY2UplbEkcwG9E5EYgAphv3etrpQ3KgckiEgKEAncopSKAl4HXrPpfAKpims8BLojIUOA1S+7nwkLgSI3jVm8Do4wMtbkZOCkiaSJSAawD7mnjMrUIIvI1kFcr+R5gjbW/Bri3RvoHliPifwLdlVIBrVPSlkFEMkRkr7VfiH4Z9eMaaQOrHkXWobu1CTAZ2GCl165/VbtsAG5VquO7AlZK9QeisWLJWXVq9TYwyshQm37Av2ocn7PSrhX6iEgG6Jc14Gel/6zbxRpuCUMHxrxm2sAankpFRybYBpwC8kXEYYnUrGN1/a3vC4BerVviFmEFsBgdjw50nVq9DYwyMtSmrn85xuTyZ9wuSikftAPkX4vIxSuJ1pHWodtARJwiEoqORHAzcGNdYtbnz67+SqkpQLaIpNRMrkO0xdvAmHZ3AFJSUvrbbLatLpfrBup+GAwGg6EuxGazHXW5XJHh4eHnan+plPoDOkyOAx2BoSvwGRAF+IuIQyk1FlgmIlFKqa+s/SSllBuQCfSWZlAkDYWQMLQDbDbbVn9//2F9+vRRNuMS22AwNBKXy6UyMzOHZWVlbaOOXp+ILAGWACilJgKLRGSmUmo9Op7dOuBh4P9Zp2yyjpOs7/+rORQRmGG6DoHL5bqhT58+bkYRGQyGpmCz2fD393dzOp03xMTExMbExNgbeeozQJxS6iR6TuivVvpfgV5Wehw/Wlr+ZEzPqGNgekQGg+GqsNlsWAZvk9HGCNvrkhORRCDR2k9Dz6HVlikDprVIOVsiU4PBYDC0OwrR8YnaJUYZGRqF3W4nNDSUwMBAQkJCePXVV3G5XFc85/Tp03z88cetVMK25YUXXiAwMJDg4GBCQ0P55ptvmpzHxo0bOXz4cPXxxIkTSU5ObvT5tds7OTmZp556qsnl6GhUPZujRo1i2rRplJSUXCYzePBggoKCCAkJITIykszMTAB8fHxau7gtxvvvv096evqVRIR2/M5vtwUztC+8vb1JTU3l0KFDbNu2jc2bN7N8+fIrnnOtKKOkpCT+8Y9/sHfvXvbv38/27dsZMGBAk/OprYyaSu32HjNmDK+//vpV59dRqHo2Dx48iIeHB++8806dcgkJCezbt48xY8bw4osvtnIpW55GKKN2jVFGhibj5+fHu+++y5tvvomIcPr0acaNG8fo0aMZPXo0e/bsAeDZZ59l165dhIaG8tprr9Ur19HJyMjA19cXT09PAHx9fTly5Aj33Xdftcy2bduYOnUqoP+N//a3vyUkJISIiAiysrLYs2cPmzZtIj4+ntDQUE6dOgXA+vXrufnmmxk+fDi7du0CwOl0Eh8fz0033URwcDCrVq0CLm/vxMREpkyZAkBRURGzZ88mKCiI4OBgPv3001Zrn9Zk3LhxnDx58ooy48ePv0Sm9r0A+Pzzz7nlllsICwvjtttuq07fuXMnoaGhhIaGEhYWRmFhIQB/+tOfqu/H0qVL67xuXl4e9957L8HBwURERLB//34Ali1bxiOPPMLEiRMZMmRI9R+I4uJioqOjCQkJYdSoUXzyyScApKSkMGHCBMLDw4mKiiIjI4MNGzaQnJzMzJkzCQ0NpbS09Ce0YhshImZr51tycrJUsXChyIQJzbstXCgN0rlz58vSunfvLpmZmVJcXCylpaUiInL8+HEJDw8XEZGEhASJjo6ulq9PrllpgwYqLCyUkJAQGTZsmDzxxBOSmJgoLpdLRowYIdnZ2SIiMmPGDNm0aZOIiADV+/Hx8fL73/9eREQefvhhWb9+fXW+EyZMkLi4OBER+eKLL+TWW28VEZFVq1ZVn1NWVibh4eGSlpZ2WXvXPF68eLEsrFGPvLy8xrVnE0APAzX71hBVz2ZlZaXExMTI22+/fZnMoEGDJCcnR0RE5s+fL4sXL64uc133Ii8vT1wul4iIrF69uvo+TJkyRXbv3i0i+r5XVlbKV199JXPnzhWXyyVOp1Oio6Nl586dl5VhwYIFsmzZMhER2bFjh4SEhIiIyNKlS2Xs2LFSVlYmOTk50rNnT6moqJANGzbIo48+Wn1+fn6+VFRUyNixY6ufq3Xr1sns2bNFRD8v3377bZ1tlJycLKGhoblDhgw5D0wX690C3ArsBVKB3cBQKz0OOAzsR/snHCQNvKfQ/u0OAofQC6ib9J4z1nSGq8Z6AKmsrGTBggWkpqZit9s5fvx4nfKNleto+Pj4kJKSwq5du0hISGD69Om89NJLPPTQQ3z44YfMnj2bpKQkPvjgAwA8PDyqeyzh4eFs27at3ryrelPh4eGcPn0agK1bt7J//342bNCuwwoKCjhx4gQeHh715rN9+3bWrVtXfdyjR4+fVOf2RGlpKaGhoYDuGc2ZM6dOuUmTJmG32wkODub5558H6r8X586dY/r06WRkZFBRUcF11+l5/1/84hfExcUxc+ZMpk6dSv/+/dm6dStbt24lLCwM0L3QEydOMH78+Euuv3v37uoe6eTJk8nNzaWgoACA6OhoPD098fT0xM/Pj6ysLIKCgli0aBHPPPMMU6ZMYdy4cRw8eJCDBw9y++23A7qXHBDQOPeA/fr1+8Tf3/9IWlpavFLqS9HeNlYC94jIEaXUPOA5IBb4DhgjIiVKqSeAPwLT68tbKTUKmIu2wKsAtiilvhCRE40qHMa0u8OxYkVbl0CTlpaG3W7Hz8+P5cuX06dPH/bt24fL5cLLy6vOc1577bVGyf0k2qiB7HY7EydOZOLEiQQFBbFmzRpWrVrF3XffjZeXF9OmTcPNTf/c3N3dq0xtsdvtOByOevOtGvqrKScivPHGG0RFRV0im5iYWG8+IkJL+/Ss+nPS2lTNGTVEQkICvr6+l6TVdy+efPJJ4uLiiImJITExkWXLlgF6KDQ6OprNmzcTERHB9u3bERGWLFnCY489dkneb731FqtXrwZg8+bNdbZP1bWr7nPNcgwfPpyUlBQ2b97MkiVLiIyM5L777iMwMJCkpKRGts6P2Gw2l81mqwD2ob3V/ye699nVEukGpAOISEKNU/8JzKpR5njgV4An8JmILEUvqP2niJRYMjuB+9BKrHHla3KNDNc8OTk5PP744yxYsAClFAUFBQQEBGCz2Vi7di1OpxOALl26VI+pA/XKdXSOHTvGiRM//gFMTU1l0KBB9O3bl759+/L8888TGxvbYD6126s+oqKiWLlyJZWVlQAcP36c4uLiK54fGRnJm2++WX184cKFBq9zLVNQUEC/fto36Jo1a6rTT506RVBQEM888wxjxozh6NGjREVF8d5771FUpB2Anz9/nuzsbObPn09qaiqpqan07duX8ePH89FHHwH6j4Ovry9du3a9/OIW6enpdOrUiVmzZrFo0SL27t3LiBEjyMnJqVZGlZWVHDp0CGj4+XE6nW6lpaU+wCSgysLmUWCzUuoc2i3QS3WcOgf4EkApFYkOIXIzOuxGuFJqPHp4brxSqpdSqhNwV41rNArTMzI0iqqhkMrKStzc3HjooYeIi4sDYN68edx///2sX7+eSZMm0blzZwCCg4Nxc3MjJCSE2NjYeuU6OkVFRTz55JPk5+fj5ubG0KFDeffddwGYOXMmOTk5jBzZcEioBx98kLlz5/L6669XD8HVxaOPPsrp06cZPXo0IkLv3r3ZuHHjZe1dNWwE8NxzzzF//nxGjRqF3W5n6dKl1UOAhstZtmwZ06ZNo1+/fkRERPD9998DsGLFChISErDb7YwcOZI777wTT09Pjhw5wtixYwE9bPvhhx/i5+d3WZ6zZ88mODiYTp06XaLk6uLAgQPEx8djs9lwd3dn5cqVeHh4sGHDBp566ikKCgpwOBz8+te/JjAwkNjYWB5//HG8vb1JSkrC29v7kvzS09PvLyoqykG78qnqjj8N3CUi31g9nlfRCgoApdQsYAwwwUqKtLbvrGMfYJiIfK2Uehnt+bwI3fuqv8tfB8ZRagcgJSVFwsPD27oYhqtgwYIFhIWF1TuPYTC0BikpKSxfvvwt4MDnn38+AfgQ+BY9tHY9gFJqILBFREZax7cBbwATRCTbSvt34LiIrLrS9ZRSLwLnROTtxpbRDNMZDC1EeHg4+/fvZ9asWQ0LGwytQH5+fj8gGNiKjuDaTSk13Pr6dqxor0qpMGAVEFOliCy+Ah6xwo6glOqnlPKz9qs+BwJTgf9oStnMMJ3B0EKkpKQ0LGQwtBJnz579X0VFRfnAVLEC5yml5gKfKqVcaOX0iCX+J/QQ3HrLyOKsiMSIyFal1I1AkpVehDZuyLby6QVUAvNFpEkTk0YZdQzE5XIZZ6kGg6HJuFwuRISBAwd+DBw4efJktemhiHyGjl90CSJyW335icifgT/XkT7up5TTvN06ADab7WhmZqazIV9wBoPBUBOXy0VGRoarrKzsh7YuS0OYnlEHwOVyRZ49e3ZPenr6gJZeK2IwGH4+iAhlZWV5a9euXYuO5NokC7fWxCijDkB4ePi5mJiYKHQgq2ygvI2LZOhA5Obm3pifnz/Jw8PjzIABA76oS8bpdLqdOXMm1uVydRo4cOBqDw+PDujczHAF3AFfLAOF9ogx7e5AxMTE/BtwL9CprctiMBg6FOXooHpbNm3a1C5f+kYZGQwGg6HNMQYMBoPBYGhzjDIyGAwGQ5tjlJHBYDAY2hyjjAwGg8HQ5vx/oS05cu1GBpEAAAAASUVORK5CYII=\n",
|
|
"text/plain": [
|
|
"<Figure size 432x288 with 57 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plot_traces(result)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Alternatively we can plot using snuffler, which will open in a seperate window."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"plot_snuffler(result, best_source)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.7.3rc1"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|