You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1725 lines
208 KiB

  1. {
  2. "cells": [
  3. {
  4. "cell_type": "markdown",
  5. "metadata": {},
  6. "source": [
  7. "# Pyrocko Notebook\n",
  8. "## Double Couple Waveform Inversion (The 2009 Aquila Earthquake)\n",
  9. "\n",
  10. "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",
  11. "Besides this Notebook you will also need to download the utils_nb.py file from this repository.\n",
  12. "\n",
  13. "_Authors:_\n",
  14. "Andreas Steinberg, Marius Isken\n",
  15. "\n",
  16. "-Nov. 2017"
  17. ]
  18. },
  19. {
  20. "cell_type": "code",
  21. "execution_count": 1,
  22. "metadata": {},
  23. "outputs": [],
  24. "source": [
  25. "%matplotlib notebook\n",
  26. "import time\n",
  27. "import os\n",
  28. "import scipy\n",
  29. "import numpy as num\n",
  30. "import matplotlib.pyplot as plt\n",
  31. "import plotly.plotly as py\n",
  32. "from collections import OrderedDict\n",
  33. "\n",
  34. "import utils_nb\n",
  35. "\n",
  36. "from pyrocko import gf, trace\n",
  37. "from pyrocko import moment_tensor as mtm\n",
  38. "from pyrocko.gf import ws, LocalEngine, Target, DCSource\n",
  39. "from pyrocko import util, pile, model, config, trace, io, pile, catalog\n",
  40. "\n",
  41. "km = 1000."
  42. ]
  43. },
  44. {
  45. "cell_type": "markdown",
  46. "metadata": {},
  47. "source": [
  48. "### Optimisation Parameters\n",
  49. "Setup of the optimisation parameters, as well as boundaries for the source parameters."
  50. ]
  51. },
  52. {
  53. "cell_type": "code",
  54. "execution_count": 2,
  55. "metadata": {},
  56. "outputs": [],
  57. "source": [
  58. "component = 'Z'\n",
  59. "f_low = 0.05 # Hz, for a lowpass filter\n",
  60. "taper = trace.CosFader(xfade=2.0) # Cosine taper, 2s fade\n",
  61. "\n",
  62. "phase = 'P' # Phase to fit\n",
  63. "tmin_fit = 15. # [s] to fit before synthetic phase onset (from GFStore)\n",
  64. "tmax_fit = 35. # [s] ... after\n",
  65. "\n",
  66. "bounds = OrderedDict([\n",
  67. " ('north_shift', (-20.*km, 20.*km)),\n",
  68. " ('east_shift', (-20.*km, 20.*km)),\n",
  69. " ('depth', (3.*km, 8.*km)),\n",
  70. " ('magnitude', (6.2, 6.4)),\n",
  71. " ('strike', (100., 140.)),\n",
  72. " ('dip', (40., 60.)),\n",
  73. " ('rake', (-100, -150.)),\n",
  74. " ('timeshift', (-20., 20.)),\n",
  75. " ])"
  76. ]
  77. },
  78. {
  79. "cell_type": "markdown",
  80. "metadata": {},
  81. "source": [
  82. "### Load the Waveforms\n",
  83. "We download the instrument-corrected seismic waveforms and use a `pyrocko.pile` to manage the data."
  84. ]
  85. },
  86. {
  87. "cell_type": "code",
  88. "execution_count": 3,
  89. "metadata": {
  90. "scrolled": true
  91. },
  92. "outputs": [
  93. {
  94. "name": "stderr",
  95. "output_type": "stream",
  96. "text": [
  97. "selecting files... done. 58 files selected.\n",
  98. "Looking at files [------------------------------------------------------] 100% \n",
  99. "Scanning files [--------------------------------------------------------] 100% \n",
  100. "Cannot read file '/media/asteinbe/data/asteinbe/trystuff/pyrocko-notebooks/data/aquila_realdata/stations_short.txt': No SEED data detected (file: /media/asteinbe/data/asteinbe/trystuff/pyrocko-notebooks/data/aquila_realdata/stations_short.txt)\n",
  101. "The following file caused problems and will be ignored:\n",
  102. "/media/asteinbe/data/asteinbe/trystuff/pyrocko-notebooks/data/aquila_realdata/stations_short.txt\n"
  103. ]
  104. }
  105. ],
  106. "source": [
  107. "# Download the instrument-corrected 2009 Aquila Earthquake data\n",
  108. "data_path = utils_nb.download_dir('aquila_realdata/')\n",
  109. "data = pile.make_pile([data_path])\n",
  110. "traces = data.all() # retrieves the raw waveform data as a 2D `numpy.array`.\n",
  111. "\n",
  112. "for tr in traces:\n",
  113. " tr.lowpass(4, f_low)"
  114. ]
  115. },
  116. {
  117. "cell_type": "markdown",
  118. "metadata": {},
  119. "source": [
  120. "### Initialize Forward Modelling Engine (Seismosizer)\n",
  121. "We download the precalculated Green's function database (`Store`) *global_2s_25km* from http://kinherd.org"
  122. ]
  123. },
  124. {
  125. "cell_type": "code",
  126. "execution_count": 4,
  127. "metadata": {},
  128. "outputs": [],
  129. "source": [
  130. "store_id = 'global_2s_25km'\n",
  131. "if not os.path.exists(store_id):\n",
  132. " ws.download_gf_store(site='kinherd', store_id=store_id)"
  133. ]
  134. },
  135. {
  136. "cell_type": "markdown",
  137. "metadata": {},
  138. "source": [
  139. "Now we fire up the `engine` to forward model synthetic seismograms on our _global_2s_25km_ GF database."
  140. ]
  141. },
  142. {
  143. "cell_type": "code",
  144. "execution_count": 5,
  145. "metadata": {},
  146. "outputs": [],
  147. "source": [
  148. "engine = gf.LocalEngine(store_superdirs=['.']) # The Path to where the gf_store(s)\n",
  149. "store = engine.get_store(store_id) # Load the store."
  150. ]
  151. },
  152. {
  153. "cell_type": "markdown",
  154. "metadata": {},
  155. "source": [
  156. "### Get GlobalCMT Start Model\n",
  157. "We use the GlobalCMT catalog to search for the 2009 Aquila Earthquake and initalize a source for the starting model."
  158. ]
  159. },
  160. {
  161. "cell_type": "code",
  162. "execution_count": 6,
  163. "metadata": {},
  164. "outputs": [],
  165. "source": [
  166. "tmin = util.str_to_time('2009-04-06 00:00:00') # beginning time of query\n",
  167. "tmax = util.str_to_time('2009-04-06 05:59:59') # ending time of query\n",
  168. "event = catalog.GlobalCMT().get_events(\n",
  169. " time_range=(tmin, tmax),\n",
  170. " magmin=6.)[0]\n",
  171. "\n",
  172. "base_source = gf.MTSource.from_pyrocko_event(event)"
  173. ]
  174. },
  175. {
  176. "cell_type": "markdown",
  177. "metadata": {},
  178. "source": [
  179. "### Station and _Target_ Setup\n",
  180. "We use the term _Target_ for a single component of a single station."
  181. ]
  182. },
  183. {
  184. "cell_type": "code",
  185. "execution_count": 7,
  186. "metadata": {},
  187. "outputs": [],
  188. "source": [
  189. "stations_list = model.load_stations('data/aquila_realdata/stations_short.txt')\n",
  190. "for s in stations_list:\n",
  191. " s.set_channels_by_name(*component.split())"
  192. ]
  193. },
  194. {
  195. "cell_type": "markdown",
  196. "metadata": {},
  197. "source": [
  198. "Next we define the `Target` - where to calculate the synthetic seismogram."
  199. ]
  200. },
  201. {
  202. "cell_type": "code",
  203. "execution_count": 8,
  204. "metadata": {},
  205. "outputs": [],
  206. "source": [
  207. "targets=[]\n",
  208. "for s in stations_list:\n",
  209. " target = Target(\n",
  210. " lat=s.lat,\n",
  211. " lon=s.lon,\n",
  212. " store_id=store_id, # The gf-store to be used for this target,\n",
  213. " interpolation='multilinear', # Interpolation method between GFStore nodes\n",
  214. " quantity='displacement',\n",
  215. " codes=s.nsl() + ('BH' + component,))\n",
  216. " targets.append(target)"
  217. ]
  218. },
  219. {
  220. "cell_type": "markdown",
  221. "metadata": {},
  222. "source": [
  223. "### Objective Function\n",
  224. "Now the objective function that will be called by `scipy.optimize`:"
  225. ]
  226. },
  227. {
  228. "cell_type": "code",
  229. "execution_count": 9,
  230. "metadata": {},
  231. "outputs": [],
  232. "source": [
  233. "source = gf.DCSource(\n",
  234. " lat=event.lat,\n",
  235. " lon=event.lon)\n",
  236. "\n",
  237. "def update_source(params):\n",
  238. " s = source\n",
  239. " s.north_shift = float(params[0])\n",
  240. " s.east_shift = float(params[1])\n",
  241. " s.depth = float(params[2])\n",
  242. " s.magnitude = float(params[3])\n",
  243. " s.strike = float(params[4])\n",
  244. " s.dip = float(params[5])\n",
  245. " s.rake = float(params[6])\n",
  246. " s.time = float(event.time - params[7])\n",
  247. " return source\n",
  248. "\n",
  249. "def process_trace(trace, tmin, tmax, lowpass=False, inplace=True):\n",
  250. " if lowpass:\n",
  251. " trace.lowpass(4, f_low)\n",
  252. " trace = trace.chop(tmin, tmax, inplace=inplace)\n",
  253. " trace.taper(taper)\n",
  254. " return trace\n",
  255. "\n",
  256. "iiter = 0\n",
  257. "\n",
  258. "def trace_fit(params, line=None):\n",
  259. " global iiter\n",
  260. " update_source(params)\n",
  261. "\n",
  262. " # Forward model synthetic seismograms\n",
  263. " response = engine.process(source, targets)\n",
  264. " syn_traces = response.pyrocko_traces()\n",
  265. "\n",
  266. " misfits = 0.\n",
  267. " norms = 0.\n",
  268. "\n",
  269. " for obs, syn, target in zip(traces, syn_traces, targets):\n",
  270. " syn_phs = store.t(phase, base_source, target)\n",
  271. " \n",
  272. " tmin = base_source.time + syn_phs - tmin_fit # start before theor. arrival\n",
  273. " tmax = base_source.time + syn_phs + tmax_fit # end after theor. arrival\n",
  274. " \n",
  275. " syn = process_trace(syn, tmin, tmax)\n",
  276. " obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=True)\n",
  277. "\n",
  278. " misfits += num.sqrt(num.sum((obs.ydata - syn.ydata)**2))\n",
  279. " norms += num.sqrt(num.sum(obs.ydata**2))\n",
  280. " \n",
  281. " misfit = num.sqrt(misfits**2 / norms**2)\n",
  282. " \n",
  283. " iiter += 1\n",
  284. "\n",
  285. " if line:\n",
  286. " data = {\n",
  287. " 'y': [misfit],\n",
  288. " 'x': [iiter],\n",
  289. " }\n",
  290. " line.data_source.stream(data)\n",
  291. "\n",
  292. " return misfit"
  293. ]
  294. },
  295. {
  296. "cell_type": "markdown",
  297. "metadata": {},
  298. "source": [
  299. "### Optimisation with SciPy\n",
  300. "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."
  301. ]
  302. },
  303. {
  304. "cell_type": "code",
  305. "execution_count": 10,
  306. "metadata": {},
  307. "outputs": [],
  308. "source": [
  309. "def solve():\n",
  310. " t = time.time()\n",
  311. "\n",
  312. " result = scipy.optimize.differential_evolution(\n",
  313. " trace_fit,\n",
  314. " args=[p],\n",
  315. " bounds=tuple(bounds.values()),\n",
  316. " maxiter=15000,\n",
  317. " tol=0.01,\n",
  318. " callback=update_plot)\n",
  319. "\n",
  320. " source = update_source(result.x)\n",
  321. " source.regularize()\n",
  322. "\n",
  323. " print(\"Time elapsed: %.1f s\" % (time.time() - t))\n",
  324. " print(\"Best model:\\n - Misfit %f\" % trace_fit(result.x))\n",
  325. " print(source)\n",
  326. " return result, source"
  327. ]
  328. },
  329. {
  330. "cell_type": "markdown",
  331. "metadata": {},
  332. "source": [
  333. "#### Running the optimization and plotting of the Convergence\n",
  334. "For plotting we use bokeh (which you might need to install)"
  335. ]
  336. },
  337. {
  338. "cell_type": "code",
  339. "execution_count": 12,
  340. "metadata": {},
  341. "outputs": [
  342. {
  343. "data": {
  344. "text/html": [
  345. "\n",
  346. " <div class=\"bk-root\">\n",
  347. " <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
  348. " <span id=\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\">Loading BokehJS ...</span>\n",
  349. " </div>"
  350. ]
  351. },
  352. "metadata": {},
  353. "output_type": "display_data"
  354. },
  355. {
  356. "data": {
  357. "application/javascript": [
  358. "\n",
  359. "(function(root) {\n",
  360. " function now() {\n",
  361. " return new Date();\n",
  362. " }\n",
  363. "\n",
  364. " var force = true;\n",
  365. "\n",
  366. " if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n",
  367. " root._bokeh_onload_callbacks = [];\n",
  368. " root._bokeh_is_loading = undefined;\n",
  369. " }\n",
  370. "\n",
  371. " var JS_MIME_TYPE = 'application/javascript';\n",
  372. " var HTML_MIME_TYPE = 'text/html';\n",
  373. " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
  374. " var CLASS_NAME = 'output_bokeh rendered_html';\n",
  375. "\n",
  376. " /**\n",
  377. " * Render data to the DOM node\n",
  378. " */\n",
  379. " function render(props, node) {\n",
  380. " var script = document.createElement(\"script\");\n",
  381. " node.appendChild(script);\n",
  382. " }\n",
  383. "\n",
  384. " /**\n",
  385. " * Handle when an output is cleared or removed\n",
  386. " */\n",
  387. " function handleClearOutput(event, handle) {\n",
  388. " var cell = handle.cell;\n",
  389. "\n",
  390. " var id = cell.output_area._bokeh_element_id;\n",
  391. " var server_id = cell.output_area._bokeh_server_id;\n",
  392. " // Clean up Bokeh references\n",
  393. " if (id != null && id in Bokeh.index) {\n",
  394. " Bokeh.index[id].model.document.clear();\n",
  395. " delete Bokeh.index[id];\n",
  396. " }\n",
  397. "\n",
  398. " if (server_id !== undefined) {\n",
  399. " // Clean up Bokeh references\n",
  400. " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
  401. " cell.notebook.kernel.execute(cmd, {\n",
  402. " iopub: {\n",
  403. " output: function(msg) {\n",
  404. " var id = msg.content.text.trim();\n",
  405. " if (id in Bokeh.index) {\n",
  406. " Bokeh.index[id].model.document.clear();\n",
  407. " delete Bokeh.index[id];\n",
  408. " }\n",
  409. " }\n",
  410. " }\n",
  411. " });\n",
  412. " // Destroy server and session\n",
  413. " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
  414. " cell.notebook.kernel.execute(cmd);\n",
  415. " }\n",
  416. " }\n",
  417. "\n",
  418. " /**\n",
  419. " * Handle when a new output is added\n",
  420. " */\n",
  421. " function handleAddOutput(event, handle) {\n",
  422. " var output_area = handle.output_area;\n",
  423. " var output = handle.output;\n",
  424. "\n",
  425. " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
  426. " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
  427. " return\n",
  428. " }\n",
  429. "\n",
  430. " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
  431. "\n",
  432. " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
  433. " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
  434. " // store reference to embed id on output_area\n",
  435. " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
  436. " }\n",
  437. " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
  438. " var bk_div = document.createElement(\"div\");\n",
  439. " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
  440. " var script_attrs = bk_div.children[0].attributes;\n",
  441. " for (var i = 0; i < script_attrs.length; i++) {\n",
  442. " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
  443. " }\n",
  444. " // store reference to server id on output_area\n",
  445. " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
  446. " }\n",
  447. " }\n",
  448. "\n",
  449. " function register_renderer(events, OutputArea) {\n",
  450. "\n",
  451. " function append_mime(data, metadata, element) {\n",
  452. " // create a DOM node to render to\n",
  453. " var toinsert = this.create_output_subarea(\n",
  454. " metadata,\n",
  455. " CLASS_NAME,\n",
  456. " EXEC_MIME_TYPE\n",
  457. " );\n",
  458. " this.keyboard_manager.register_events(toinsert);\n",
  459. " // Render to node\n",
  460. " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
  461. " render(props, toinsert[toinsert.length - 1]);\n",
  462. " element.append(toinsert);\n",
  463. " return toinsert\n",
  464. " }\n",
  465. "\n",
  466. " /* Handle when an output is cleared or removed */\n",
  467. " events.on('clear_output.CodeCell', handleClearOutput);\n",
  468. " events.on('delete.Cell', handleClearOutput);\n",
  469. "\n",
  470. " /* Handle when a new output is added */\n",
  471. " events.on('output_added.OutputArea', handleAddOutput);\n",
  472. "\n",
  473. " /**\n",
  474. " * Register the mime type and append_mime function with output_area\n",
  475. " */\n",
  476. " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
  477. " /* Is output safe? */\n",
  478. " safe: true,\n",
  479. " /* Index of renderer in `output_area.display_order` */\n",
  480. " index: 0\n",
  481. " });\n",
  482. " }\n",
  483. "\n",
  484. " // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
  485. " if (root.Jupyter !== undefined) {\n",
  486. " var events = require('base/js/events');\n",
  487. " var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
  488. "\n",
  489. " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
  490. " register_renderer(events, OutputArea);\n",
  491. " }\n",
  492. " }\n",
  493. "\n",
  494. " \n",
  495. " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
  496. " root._bokeh_timeout = Date.now() + 5000;\n",
  497. " root._bokeh_failed_load = false;\n",
  498. " }\n",
  499. "\n",
  500. " var NB_LOAD_WARNING = {'data': {'text/html':\n",
  501. " \"<div style='background-color: #fdd'>\\n\"+\n",
  502. " \"<p>\\n\"+\n",
  503. " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
  504. " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
  505. " \"</p>\\n\"+\n",
  506. " \"<ul>\\n\"+\n",
  507. " \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
  508. " \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
  509. " \"</ul>\\n\"+\n",
  510. " \"<code>\\n\"+\n",
  511. " \"from bokeh.resources import INLINE\\n\"+\n",
  512. " \"output_notebook(resources=INLINE)\\n\"+\n",
  513. " \"</code>\\n\"+\n",
  514. " \"</div>\"}};\n",
  515. "\n",
  516. " function display_loaded() {\n",
  517. " var el = document.getElementById(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\");\n",
  518. " if (el != null) {\n",
  519. " el.textContent = \"BokehJS is loading...\";\n",
  520. " }\n",
  521. " if (root.Bokeh !== undefined) {\n",
  522. " if (el != null) {\n",
  523. " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
  524. " }\n",
  525. " } else if (Date.now() < root._bokeh_timeout) {\n",
  526. " setTimeout(display_loaded, 100)\n",
  527. " }\n",
  528. " }\n",
  529. "\n",
  530. "\n",
  531. " function run_callbacks() {\n",
  532. " try {\n",
  533. " root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
  534. " }\n",
  535. " finally {\n",
  536. " delete root._bokeh_onload_callbacks\n",
  537. " }\n",
  538. " console.info(\"Bokeh: all callbacks have finished\");\n",
  539. " }\n",
  540. "\n",
  541. " function load_libs(js_urls, callback) {\n",
  542. " root._bokeh_onload_callbacks.push(callback);\n",
  543. " if (root._bokeh_is_loading > 0) {\n",
  544. " console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
  545. " return null;\n",
  546. " }\n",
  547. " if (js_urls == null || js_urls.length === 0) {\n",
  548. " run_callbacks();\n",
  549. " return null;\n",
  550. " }\n",
  551. " console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
  552. " root._bokeh_is_loading = js_urls.length;\n",
  553. " for (var i = 0; i < js_urls.length; i++) {\n",
  554. " var url = js_urls[i];\n",
  555. " var s = document.createElement('script');\n",
  556. " s.src = url;\n",
  557. " s.async = false;\n",
  558. " s.onreadystatechange = s.onload = function() {\n",
  559. " root._bokeh_is_loading--;\n",
  560. " if (root._bokeh_is_loading === 0) {\n",
  561. " console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
  562. " run_callbacks()\n",
  563. " }\n",
  564. " };\n",
  565. " s.onerror = function() {\n",
  566. " console.warn(\"failed to load library \" + url);\n",
  567. " };\n",
  568. " console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
  569. " document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
  570. " }\n",
  571. " };var element = document.getElementById(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\");\n",
  572. " if (element == null) {\n",
  573. " console.log(\"Bokeh: ERROR: autoload.js configured with elementid '3bf01df0-be96-45ce-b4c3-33bf2e4fe80b' but no matching script tag was found. \")\n",
  574. " return false;\n",
  575. " }\n",
  576. "\n",
  577. " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.13.0.min.js\"];\n",
  578. "\n",
  579. " var inline_js = [\n",
  580. " function(Bokeh) {\n",
  581. " Bokeh.set_log_level(\"info\");\n",
  582. " },\n",
  583. " \n",
  584. " function(Bokeh) {\n",
  585. " \n",
  586. " },\n",
  587. " function(Bokeh) {\n",
  588. " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n",
  589. " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n",
  590. " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n",
  591. " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n",
  592. " console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n",
  593. " Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n",
  594. " }\n",
  595. " ];\n",
  596. "\n",
  597. " function run_inline_js() {\n",
  598. " \n",
  599. " if ((root.Bokeh !== undefined) || (force === true)) {\n",
  600. " for (var i = 0; i < inline_js.length; i++) {\n",
  601. " inline_js[i].call(root, root.Bokeh);\n",
  602. " }if (force === true) {\n",
  603. " display_loaded();\n",
  604. " }} else if (Date.now() < root._bokeh_timeout) {\n",
  605. " setTimeout(run_inline_js, 100);\n",
  606. " } else if (!root._bokeh_failed_load) {\n",
  607. " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
  608. " root._bokeh_failed_load = true;\n",
  609. " } else if (force !== true) {\n",
  610. " var cell = $(document.getElementById(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\")).parents('.cell').data().cell;\n",
  611. " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
  612. " }\n",
  613. "\n",
  614. " }\n",
  615. "\n",
  616. " if (root._bokeh_is_loading === 0) {\n",
  617. " console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
  618. " run_inline_js();\n",
  619. " } else {\n",
  620. " load_libs(js_urls, function() {\n",
  621. " console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
  622. " run_inline_js();\n",
  623. " });\n",
  624. " }\n",
  625. "}(window));"
  626. ],
  627. "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(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\");\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) { callback() });\n }\n finally {\n delete root._bokeh_onload_callbacks\n }\n console.info(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(js_urls, callback) {\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.log(\"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.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = js_urls.length;\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var s = document.createElement('script');\n s.src = url;\n s.async = false;\n s.onreadystatechange = s.onload = function() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.log(\"Bokeh: all BokehJS libraries loaded\");\n run_callbacks()\n }\n };\n s.onerror = function() {\n console.warn(\"failed to load library \" + url);\n };\n console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.getElementsByTagName(\"head\")[0].appendChild(s);\n }\n };var element = document.getElementById(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\");\n if (element == null) {\n console.log(\"Bokeh: ERROR: autoload.js configured with elementid '3bf01df0-be96-45ce-b4c3-33bf2e4fe80b' but no matching script tag was found. \")\n return false;\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.13.0.min.js\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n \n },\n function(Bokeh) {\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n }\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(\"3bf01df0-be96-45ce-b4c3-33bf2e4fe80b\")).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.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(js_urls, function() {\n console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));"
  628. },
  629. "metadata": {},
  630. "output_type": "display_data"
  631. },
  632. {
  633. "data": {
  634. "text/html": [
  635. "\n",
  636. "\n",
  637. "\n",
  638. "\n",
  639. "\n",
  640. "\n",
  641. " <div class=\"bk-root\" id=\"78e46b9c-7bd8-45e4-9033-4cbeedc45dca\"></div>\n"
  642. ]
  643. },
  644. "metadata": {},
  645. "output_type": "display_data"
  646. },
  647. {
  648. "data": {
  649. "application/javascript": [
  650. "(function(root) {\n",
  651. " function embed_document(root) {\n",
  652. " \n",
  653. " var docs_json = {\"14985bb5-03b0-4ecf-aa6b-7776520ba33f\":{\"roots\":{\"references\":[{\"attributes\":{\"axis_label\":\"# Iteration\",\"formatter\":{\"id\":\"59caea6c-b1b0-4974-a3f6-dd53b79c81e0\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"57499cb6-dbb9-4f81-890d-276d7743e0a4\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"5f6332c2-889f-434d-8dc7-0e9c65d41549\",\"type\":\"BasicTicker\"}},\"id\":\"4265d19a-4f99-4363-aa6d-32dbca91858a\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"66334339-49b3-4774-bf99-a000ddbd22eb\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"98e726cf-d738-4917-babe-519f23989fa7\",\"type\":\"HelpTool\"},{\"attributes\":{},\"id\":\"5cdcaedd-1cf6-464d-8351-a37d43cdbdc1\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{},\"id\":\"a6da10d8-b40f-4c18-8407-b6dd5c2ab061\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"ea77f3d8-a717-4c5a-abe3-288848be4b58\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"62602f3a-0566-440c-a0ca-a2cf3a60109c\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"5f6332c2-889f-434d-8dc7-0e9c65d41549\",\"type\":\"BasicTicker\"},{\"attributes\":{\"source\":{\"id\":\"6d018c71-540a-48cf-9f72-a9c5bae6d5cc\",\"type\":\"ColumnDataSource\"}},\"id\":\"3ab34d58-091d-438e-af46-f29395dd85af\",\"type\":\"CDSView\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"d964154e-19cd-4478-bf50-3c417d13dbd8\",\"type\":\"PanTool\"},{\"id\":\"ea77f3d8-a717-4c5a-abe3-288848be4b58\",\"type\":\"WheelZoomTool\"},{\"id\":\"7da40055-4cc8-43b5-9659-14f047de0fad\",\"type\":\"BoxZoomTool\"},{\"id\":\"67c6f324-602a-4f2f-9d19-2945e9e96feb\",\"type\":\"SaveTool\"},{\"id\":\"62602f3a-0566-440c-a0ca-a2cf3a60109c\",\"type\":\"ResetTool\"},{\"id\":\"98e726cf-d738-4917-babe-519f23989fa7\",\"type\":\"HelpTool\"}]},\"id\":\"228229a8-72ac-490f-8761-402ee576d311\",\"type\":\"Toolbar\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"57499cb6-dbb9-4f81-890d-276d7743e0a4\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"bf1c343f-2bbc-4770-b886-3b47948a511d\",\"type\":\"BasicTicker\"}},\"id\":\"cb3fc096-8422-440b-a6a2-f9653ba53d88\",\"type\":\"Grid\"},{\"attributes\":{\"plot\":{\"id\":\"57499cb6-dbb9-4f81-890d-276d7743e0a4\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"5f6332c2-889f-434d-8dc7-0e9c65d41549\",\"type\":\"BasicTicker\"}},\"id\":\"8f573ccd-5485-493f-88c0-f1918c9e2253\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"d964154e-19cd-4478-bf50-3c417d13dbd8\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"bf1c343f-2bbc-4770-b886-3b47948a511d\",\"type\":\"BasicTicker\"},{\"attributes\":{\"fill_color\":{\"value\":\"#1f77b4\"},\"line_color\":{\"value\":\"#1f77b4\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"bf586299-f647-4f8a-bb95-d78b5b99ef21\",\"type\":\"Circle\"},{\"attributes\":{\"below\":[{\"id\":\"4265d19a-4f99-4363-aa6d-32dbca91858a\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"a180399d-26d2-4f9a-80be-85598b95a737\",\"type\":\"LinearAxis\"}],\"plot_height\":300,\"plot_width\":800,\"renderers\":[{\"id\":\"4265d19a-4f99-4363-aa6d-32dbca91858a\",\"type\":\"LinearAxis\"},{\"id\":\"8f573ccd-5485-493f-88c0-f1918c9e2253\",\"type\":\"Grid\"},{\"id\":\"a180399d-26d2-4f9a-80be-85598b95a737\",\"type\":\"LinearAxis\"},{\"id\":\"cb3fc096-8422-440b-a6a2-f9653ba53d88\",\"type\":\"Grid\"},{\"id\":\"fcda33c3-f73e-4465-a239-c03536a38e74\",\"type\":\"BoxAnnotation\"},{\"id\":\"a291c3f8-a25b-4aae-8909-644ee4cca6ec\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"371b9ce2-9015-40ec-9006-c103f15fcc01\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"228229a8-72ac-490f-8761-402ee576d311\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"cd0f62a4-c80a-4bfd-9922-d9ec0eacc361\",\"type\":\"DataRange1d\"},\"x_scale\":{\"id\":\"a6da10d8-b40f-4c18-8407-b6dd5c2ab061\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"5b288ec2-9ddd-4ead-a17e-c3f590478201\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"66334339-49b3-4774-bf99-a000ddbd22eb\",\"type\":\"LinearScale\"}},\"id\":\"57499cb6-dbb9-4f81-890d-276d7743e0a4\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"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\":\"2744aca2-7c30-4ede-b62b-2fe328652f85\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"59caea6c-b1b0-4974-a3f6-dd53b79c81e0\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"callback\":null},\"id\":\"5b288ec2-9ddd-4ead-a17e-c3f590478201\",\"type\":\"DataRange1d\"},{\"attributes\":{\"axis_label\":\"Misfit\",\"formatter\":{\"id\":\"5cdcaedd-1cf6-464d-8351-a37d43cdbdc1\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"57499cb6-dbb9-4f81-890d-276d7743e0a4\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"bf1c343f-2bbc-4770-b886-3b47948a511d\",\"type\":\"BasicTicker\"}},\"id\":\"a180399d-26d2-4f9a-80be-85598b95a737\",\"type\":\"LinearAxis\"},{\"attributes\":{\"data_source\":{\"id\":\"6d018c71-540a-48cf-9f72-a9c5bae6d5cc\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"bf586299-f647-4f8a-bb95-d78b5b99ef21\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2744aca2-7c30-4ede-b62b-2fe328652f85\",\"type\":\"Circle\"},\"selection_glyph\":null,\"view\":{\"id\":\"3ab34d58-091d-438e-af46-f29395dd85af\",\"type\":\"CDSView\"}},\"id\":\"a291c3f8-a25b-4aae-8909-644ee4cca6ec\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"67c6f324-602a-4f2f-9d19-2945e9e96feb\",\"type\":\"SaveTool\"},{\"attributes\":{\"callback\":null},\"id\":\"cd0f62a4-c80a-4bfd-9922-d9ec0eacc361\",\"type\":\"DataRange1d\"},{\"attributes\":{\"plot\":null,\"text\":\"SciPy Optimisation Progress\"},\"id\":\"371b9ce2-9015-40ec-9006-c103f15fcc01\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"7e4187f9-0480-4b49-a8ef-9c8b8d760223\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"18892b70-5965-4999-a93b-593b7d284091\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":[],\"y\":[]},\"selected\":{\"id\":\"7e4187f9-0480-4b49-a8ef-9c8b8d760223\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"18892b70-5965-4999-a93b-593b7d284091\",\"type\":\"UnionRenderers\"}},\"id\":\"6d018c71-540a-48cf-9f72-a9c5bae6d5cc\",\"type\":\"ColumnDataSource\"},{\"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},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"fcda33c3-f73e-4465-a239-c03536a38e74\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"overlay\":{\"id\":\"fcda33c3-f73e-4465-a239-c03536a38e74\",\"type\":\"BoxAnnotation\"}},\"id\":\"7da40055-4cc8-43b5-9659-14f047de0fad\",\"type\":\"BoxZoomTool\"}],\"root_ids\":[\"57499cb6-dbb9-4f81-890d-276d7743e0a4\"]},\"title\":\"Bokeh Application\",\"version\":\"0.13.0\"}};\n",
  654. " var render_items = [{\"docid\":\"14985bb5-03b0-4ecf-aa6b-7776520ba33f\",\"notebook_comms_target\":\"bdb573f6-f2b0-4f0c-a676-dd3453807f4d\",\"roots\":{\"57499cb6-dbb9-4f81-890d-276d7743e0a4\":\"78e46b9c-7bd8-45e4-9033-4cbeedc45dca\"}}];\n",
  655. " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
  656. "\n",
  657. " }\n",
  658. " if (root.Bokeh !== undefined) {\n",
  659. " embed_document(root);\n",
  660. " } else {\n",
  661. " var attempts = 0;\n",
  662. " var timer = setInterval(function(root) {\n",
  663. " if (root.Bokeh !== undefined) {\n",
  664. " embed_document(root);\n",
  665. " clearInterval(timer);\n",
  666. " }\n",
  667. " attempts++;\n",
  668. " if (attempts > 100) {\n",
  669. " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\")\n",
  670. " clearInterval(timer);\n",
  671. " }\n",
  672. " }, 10, root)\n",
  673. " }\n",
  674. "})(window);"
  675. ],
  676. "application/vnd.bokehjs_exec.v0+json": ""
  677. },
  678. "metadata": {
  679. "application/vnd.bokehjs_exec.v0+json": {
  680. "id": "57499cb6-dbb9-4f81-890d-276d7743e0a4"
  681. }
  682. },
  683. "output_type": "display_data"
  684. },
  685. {
  686. "name": "stdout",
  687. "output_type": "stream",
  688. "text": [
  689. "Time elapsed: 112.5 s\n",
  690. "Best model:\n",
  691. " - Misfit 1.255760\n",
  692. "--- !pf.DCSource\n",
  693. "lat: 42.29\n",
  694. "lon: 13.35\n",
  695. "north_shift: 7133.841195788899\n",
  696. "east_shift: 7690.721161726071\n",
  697. "elevation: 0.0\n",
  698. "depth: 3063.7232231645157\n",
  699. "time: 2009-04-06 01:32:29.297190\n",
  700. "stf_mode: post\n",
  701. "magnitude: 6.214677659485893\n",
  702. "strike: 134.6072161989871\n",
  703. "dip: 51.665046373603204\n",
  704. "rake: -143.50897602844884\n",
  705. "\n"
  706. ]
  707. }
  708. ],
  709. "source": [
  710. "from bokeh.io import push_notebook, show, output_notebook\n",
  711. "from bokeh.plotting import figure\n",
  712. "output_notebook()\n",
  713. "\n",
  714. "f = figure(title='SciPy Optimisation Progress',\n",
  715. " x_axis_label='# Iteration',\n",
  716. " y_axis_label='Misfit',\n",
  717. " plot_width=800,\n",
  718. " plot_height=300)\n",
  719. "p = f.scatter([], [])\n",
  720. "show(f, notebook_handle=True)\n",
  721. "\n",
  722. "def update_plot(*a, **ka):\n",
  723. " push_notebook()\n",
  724. "\n",
  725. "# Start the optimisation\n",
  726. "result, best_source = solve()"
  727. ]
  728. },
  729. {
  730. "cell_type": "markdown",
  731. "metadata": {},
  732. "source": [
  733. "### Plot the Results\n",
  734. "Now we plot the synthetic waveforms produced by our the best model vs. the observed traces."
  735. ]
  736. },
  737. {
  738. "cell_type": "code",
  739. "execution_count": 13,
  740. "metadata": {},
  741. "outputs": [],
  742. "source": [
  743. "def plot_traces(result):\n",
  744. " nstations = len(stations_list)\n",
  745. " response = engine.process(source, targets)\n",
  746. " syn_traces = response.pyrocko_traces()\n",
  747. "\n",
  748. " fig, axes = plt.subplots(nstations, squeeze=True, sharex=True)\n",
  749. " fig.subplots_adjust(hspace=0)\n",
  750. " plt.setp([ax.get_xticklabels() for ax in axes[:-1]], visible=False)\n",
  751. "\n",
  752. " for istation, (obs, syn, target) in enumerate(zip(traces, syn_traces, targets)):\n",
  753. " ax = axes[istation]\n",
  754. " tp = store.t(phase, base_source, target)\n",
  755. " tp_onset = base_source.time + tp\n",
  756. " tmin = tp_onset - tmin_fit\n",
  757. " tmax = tp_onset + tmax_fit\n",
  758. " \n",
  759. " syn = process_trace(syn, tmin, tmax)\n",
  760. " obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=False)\n",
  761. " \n",
  762. " s1 = ax.plot(obs.get_xdata(), obs.ydata, color='b')\n",
  763. " s2 = ax.plot(syn.get_xdata(), syn.ydata, color='r')\n",
  764. " s3 = ax.plot([tp_onset, tp_onset], [tr.ydata.min(), tr.ydata.max()], 'k-', lw=2)\n",
  765. "\n",
  766. " ax.text(-.2, 0.5, stations_list[istation].station,\n",
  767. " transform=ax.transAxes)\n",
  768. " ax.set_yticklabels([], visible=False)\n",
  769. "\n",
  770. " axes[-1].set_xlabel('Time [s]')\n",
  771. " plt.suptitle('Waveform fits for %s-Phase and component %s' % (phase, component))\n",
  772. " plt.legend(\n",
  773. " (s1[0], s2[0], s3[0]),\n",
  774. " ('Data', 'Synthetic','%s Phase-onset' % phase),\n",
  775. " loc='upper center',\n",
  776. " bbox_to_anchor=(0.5, -2.),\n",
  777. " fancybox=True, shadow=True, ncol=5)\n",
  778. " \n",
  779. " plt.show()"
  780. ]
  781. },
  782. {
  783. "cell_type": "code",
  784. "execution_count": 20,
  785. "metadata": {},
  786. "outputs": [],
  787. "source": [
  788. "def plot_snuffler(result, source):\n",
  789. " engine = gf.get_engine()\n",
  790. " response = engine.process(source, targets)\n",
  791. " syn_traces = response.pyrocko_traces()\n",
  792. " obs_traces = []\n",
  793. " \n",
  794. " for obs, syn, target in zip(traces, syn_traces, targets):\n",
  795. " tp = store.t('P', base_source, target)\n",
  796. " tmin = base_source.time + tp - tmin_fit\n",
  797. " tmax = base_source.time + tp + tmax_fit\n",
  798. "\n",
  799. " syn = process_trace(syn, tmin, tmax)\n",
  800. " obs = process_trace(obs, tmin, tmax, lowpass=False, inplace=False)\n",
  801. "\n",
  802. " obs_traces.append(obs)\n",
  803. "\n",
  804. " trace.snuffle(obs_traces + syn_traces, stations=stations_list, events= [event])"
  805. ]
  806. },
  807. {
  808. "cell_type": "markdown",
  809. "metadata": {},
  810. "source": [
  811. "Next we plot the station distribution with folium (which you might need to install)"
  812. ]
  813. },
  814. {
  815. "cell_type": "code",
  816. "execution_count": 16,
  817. "metadata": {},
  818. "outputs": [
  819. {
  820. "data": {
  821. "text/html": [
  822. "<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+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgPHN0eWxlPiNtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEgewogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICB3aWR0aDogMTAwLjAlOwogICAgICAgIGhlaWdodDogMTAwLjAlOwogICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgdG9wOiAwLjAlOwogICAgICAgIH0KICAgIDwvc3R5bGU+CjwvaGVhZD4KPGJvZHk+ICAgIAogICAgCiAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxIiA+PC9kaXY+CjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKICAgIAogICAgICAgIHZhciBib3VuZHMgPSBudWxsOwogICAgCgogICAgdmFyIG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSA9IEwubWFwKAogICAgICAgICdtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEnLCB7CiAgICAgICAgY2VudGVyOiBbNDIuMjksIDEzLjM1XSwKICAgICAgICB6b29tOiAzLAogICAgICAgIG1heEJvdW5kczogYm91bmRzLAogICAgICAgIGxheWVyczogW10sCiAgICAgICAgd29ybGRDb3B5SnVtcDogZmFsc2UsCiAgICAgICAgY3JzOiBMLkNSUy5FUFNHMzg1NywKICAgICAgICB6b29tQ29udHJvbDogdHJ1ZSwKICAgICAgICB9KTsKCiAgICAKICAgIAogICAgdmFyIHRpbGVfbGF5ZXJfOTk1NTRkMGY3ODRlNDNmZTkyNWEyZmM5OTYyZjkzMGYgPSBMLnRpbGVMYXllcigKICAgICAgICAnaHR0cHM6Ly9zdGFtZW4tdGlsZXMte3N9LmEuc3NsLmZhc3RseS5uZXQvdGVycmFpbi97en0ve3h9L3t5fS5qcGcnLAogICAgICAgIHsKICAgICAgICAiYXR0cmlidXRpb24iOiBudWxsLAogICAgICAgICJkZXRlY3RSZXRpbmEiOiBmYWxzZSwKICAgICAgICAibWF4TmF0aXZlWm9vbSI6IDE4LAogICAgICAgICJtYXhab29tIjogMTgsCiAgICAgICAgIm1pblpvb20iOiAwLAogICAgICAgICJub1dyYXAiOiBmYWxzZSwKICAgICAgICAic3ViZG9tYWlucyI6ICJhYmMiCn0pLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAKICAgICAgICB2YXIgbWFya2VyXzlhNzM3NzVmNTEwNDQ2YzE5YmEzNTllYTI2MDRmNmVmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0Mi4yOSwgMTMuMzVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKCiAgICAgICAgICAgICAgICB2YXIgaWNvbl9jZjZkMGVmM2QwNTM0MzYyYWM5ZWI0NDQ2ZjBkYjIzZCA9IEwuQXdlc29tZU1hcmtlcnMuaWNvbih7CiAgICAgICAgICAgICAgICAgICAgaWNvbjogJ2luZm8tc2lnbicsCiAgICAgICAgICAgICAgICAgICAgaWNvbkNvbG9yOiAnd2hpdGUnLAogICAgICAgICAgICAgICAgICAgIG1hcmtlckNvbG9yOiAncmVkJywKICAgICAgICAgICAgICAgICAgICBwcmVmaXg6ICdnbHlwaGljb24nLAogICAgICAgICAgICAgICAgICAgIGV4dHJhQ2xhc3NlczogJ2ZhLXJvdGF0ZS0wJwogICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgbWFya2VyXzlhNzM3NzVmNTEwNDQ2YzE5YmEzNTllYTI2MDRmNmVmLnNldEljb24oaWNvbl9jZjZkMGVmM2QwNTM0MzYyYWM5ZWI0NDQ2ZjBkYjIzZCk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yMzYxMDI2MTI1MGI0MDVhYWZlNjJiN2Q2Yzc3ZDM3OCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzgxNzMzODhmM2E5MzQxODlhNWE4Mjc3ZDc2N2ZhYzRmID0gJCgnPGRpdiBpZD0iaHRtbF84MTczMzg4ZjNhOTM0MTg5YTVhODI3N2Q3NjdmYWM0ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MjAwOSBBcXVpbGEgRWFydGhxdWFrZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjM2MTAyNjEyNTBiNDA1YWFmZTYyYjdkNmM3N2QzNzguc2V0Q29udGVudChodG1sXzgxNzMzODhmM2E5MzQxODlhNWE4Mjc3ZDc2N2ZhYzRmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOWE3Mzc3NWY1MTA0NDZjMTliYTM1OWVhMjYwNGY2ZWYuYmluZFBvcHVwKHBvcHVwXzIzNjEwMjYxMjUwYjQwNWFhZmU2MmI3ZDZjNzdkMzc4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNWMzZmIwOGI1NWQ0NGViOGFjMjE1MTU3ZjQ3NTZhMjkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzY1LjU1OTgsIC0xNjcuOTI2N10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjJkNGU4ODc5YjY4NGQwZWE4MmUwNTVkZDMyNDNmYmIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9kZTQ1MGIwYTM3MWU0OTA4YWFiMDY3MmJlYWIwZTUwMSA9ICQoJzxkaXYgaWQ9Imh0bWxfZGU0NTBiMGEzNzFlNDkwOGFhYjA2NzJiZWFiMGU1MDEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlROQTwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjJkNGU4ODc5YjY4NGQwZWE4MmUwNTVkZDMyNDNmYmIuc2V0Q29udGVudChodG1sX2RlNDUwYjBhMzcxZTQ5MDhhYWIwNjcyYmVhYjBlNTAxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNWMzZmIwOGI1NWQ0NGViOGFjMjE1MTU3ZjQ3NTZhMjkuYmluZFBvcHVwKHBvcHVwXzIyZDRlODg3OWI2ODRkMGVhODJlMDU1ZGQzMjQzZmJiKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZTk1Mjc5ZTlhNjk4NDlmOThlZjYzZjE0ZWZkY2Y0N2QgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzU1LjQ2ODk0LCAtMTMzLjEyMjk3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8zOTJjNGVlMDFkMjg0ODU4YmIzMjRmMGJhYmVjMzFlNSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2M3NjYzYWIxYjg0MDQzZGZiYjAwZTYzNDEyYzFlODFiID0gJCgnPGRpdiBpZD0iaHRtbF9jNzY2M2FiMWI4NDA0M2RmYmIwMGU2MzQxMmMxZTgxYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+Q1JBRzwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMzkyYzRlZTAxZDI4NDg1OGJiMzI0ZjBiYWJlYzMxZTUuc2V0Q29udGVudChodG1sX2M3NjYzYWIxYjg0MDQzZGZiYjAwZTYzNDEyYzFlODFiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZTk1Mjc5ZTlhNjk4NDlmOThlZjYzZjE0ZWZkY2Y0N2QuYmluZFBvcHVwKHBvcHVwXzM5MmM0ZWUwMWQyODQ4NThiYjMyNGYwYmFiZWMzMWU1KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNGNjODgxN2Y3N2U3NGQ2OWFmNzdmNTEzYTk0NGM2OTggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzQ5LjI1NiwgLTU3LjUwNDJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzY4ZWZjMTkyYjU3OTQ1M2ZiZDZiYTg0YzllYmE2NjU3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjg0M2JiOTgyNjNjNGJjYmE0NmU2MWUxZDc1YjNmZjIgPSAkKCc8ZGl2IGlkPSJodG1sXzI4NDNiYjk4MjYzYzRiY2JhNDZlNjFlMWQ3NWIzZmYyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5EUkxOPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF82OGVmYzE5MmI1Nzk0NTNmYmQ2YmE4NGM5ZWJhNjY1Ny5zZXRDb250ZW50KGh0bWxfMjg0M2JiOTgyNjNjNGJjYmE0NmU2MWUxZDc1YjNmZjIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80Y2M4ODE3Zjc3ZTc0ZDY5YWY3N2Y1MTNhOTQ0YzY5OC5iaW5kUG9wdXAocG9wdXBfNjhlZmMxOTJiNTc5NDUzZmJkNmJhODRjOWViYTY2NTcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yZjU4OTljNzU4NGE0YTkyYThmNjJkNmQ3Mjg2OWJlNCA9IEwubWFya2VyKAogICAgICAgICAgICBbNjguMzA2NSwgLTEzMy41MjU0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mZTkzMWIxNzhmOTY0OTdlOTkyNzYzNjRjYjRhNmVlYiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2E5OTFmYzU3YWJkZDQ5ZGI5N2RiNWE0NThlMTI2MWU1ID0gJCgnPGRpdiBpZD0iaHRtbF9hOTkxZmM1N2FiZGQ0OWRiOTdkYjVhNDU4ZTEyNjFlNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+SU5LPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9mZTkzMWIxNzhmOTY0OTdlOTkyNzYzNjRjYjRhNmVlYi5zZXRDb250ZW50KGh0bWxfYTk5MWZjNTdhYmRkNDlkYjk3ZGI1YTQ1OGUxMjYxZTUpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8yZjU4OTljNzU4NGE0YTkyYThmNjJkNmQ3Mjg2OWJlNC5iaW5kUG9wdXAocG9wdXBfZmU5MzFiMTc4Zjk2NDk3ZTk5Mjc2MzY0Y2I0YTZlZWIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mNGY3YWU2ZDY0NDk0YTY0OGZiZDQwYjhiNDYyZmUwMyA9IEwubWFya2VyKAogICAgICAgICAgICBbNzQuNjg5MiwgLTk0Ljg5NjJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJmNTc1YWE0YzdjNjQwMzlhODMxZGE2MmMxZWE5YWE0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDBlZjAzYzFmNzZhNDJhYWJkMmRkOWRhMmRlZDg0MmUgPSAkKCc8ZGl2IGlkPSJodG1sX2QwZWYwM2MxZjc2YTQyYWFiZDJkZDlkYTJkZWQ4NDJlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5SRVM8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzJmNTc1YWE0YzdjNjQwMzlhODMxZGE2MmMxZWE5YWE0LnNldENvbnRlbnQoaHRtbF9kMGVmMDNjMWY3NmE0MmFhYmQyZGQ5ZGEyZGVkODQyZSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2Y0ZjdhZTZkNjQ0OTRhNjQ4ZmJkNDBiOGI0NjJmZTAzLmJpbmRQb3B1cChwb3B1cF8yZjU3NWFhNGM3YzY0MDM5YTgzMWRhNjJjMWVhOWFhNCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzY0ZjNiMGY4NDRjYTQ3YzQ5NWZkMjYwY2ViNDBjZGRmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsxNy42Njg1MywgLTYxLjc4NTU3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jMThkYmE2NDU1N2E0NTU1YjQxM2JhZWZiMDBhNWVhZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzlkZmEzMDVhODI4MjRiMjViZjI2ZjEwODJkMDYxY2NjID0gJCgnPGRpdiBpZD0iaHRtbF85ZGZhMzA1YTgyODI0YjI1YmYyNmYxMDgyZDA2MWNjYyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QU5XQjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzE4ZGJhNjQ1NTdhNDU1NWI0MTNiYWVmYjAwYTVlYWYuc2V0Q29udGVudChodG1sXzlkZmEzMDVhODI4MjRiMjViZjI2ZjEwODJkMDYxY2NjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNjRmM2IwZjg0NGNhNDdjNDk1ZmQyNjBjZWI0MGNkZGYuYmluZFBvcHVwKHBvcHVwX2MxOGRiYTY0NTU3YTQ1NTViNDEzYmFlZmIwMGE1ZWFmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMTcyY2M4ZWJiNThkNDlkZmE0OWMzZGI0NWFhNTA0NDEgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzIxLjUxMTQ5LCAtNzEuMTMyN10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYjE5Zjg3NTZiYmVhNDUzZGJhNmY3ZTJkYTVmNWZkYTMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81MjliZGI2MTZjMjY0ODFmYTE0Mzc3Mzg1MWIwY2ExNCA9ICQoJzxkaXYgaWQ9Imh0bWxfNTI5YmRiNjE2YzI2NDgxZmExNDM3NzM4NTFiMGNhMTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkdSVEs8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2IxOWY4NzU2YmJlYTQ1M2RiYTZmN2UyZGE1ZjVmZGEzLnNldENvbnRlbnQoaHRtbF81MjliZGI2MTZjMjY0ODFmYTE0Mzc3Mzg1MWIwY2ExNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzE3MmNjOGViYjU4ZDQ5ZGZhNDljM2RiNDVhYTUwNDQxLmJpbmRQb3B1cChwb3B1cF9iMTlmODc1NmJiZWE0NTNkYmE2ZjdlMmRhNWY1ZmRhMykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzQ2NmMxZjRlYWMyMTRiMjk4NTg0NzY4MjY3OWMwODI0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsxOC4yMjYwNSwgLTc3LjUzNDU0XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hOGE0YzA3ZDJmYTM0YmNjYjYxYTE1NTk0ZmY0NjM4MiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMwZTYwOTMwMzc0NjQ1YjBhOTY5M2YxYzIwMmRiZDI0ID0gJCgnPGRpdiBpZD0iaHRtbF8zMGU2MDkzMDM3NDY0NWIwYTk2OTNmMWMyMDJkYmQyNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+TVRESjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYThhNGMwN2QyZmEzNGJjY2I2MWExNTU5NGZmNDYzODIuc2V0Q29udGVudChodG1sXzMwZTYwOTMwMzc0NjQ1YjBhOTY5M2YxYzIwMmRiZDI0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNDY2YzFmNGVhYzIxNGIyOTg1ODQ3NjgyNjc5YzA4MjQuYmluZFBvcHVwKHBvcHVwX2E4YTRjMDdkMmZhMzRiY2NiNjFhMTU1OTRmZjQ2MzgyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMDI5N2Y1NDEyOGNmNDNkY2I4OGEwOGMwMjIwZjNmNjIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE0LjM5MjAyLCAtMTYuOTU1NDddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2FmMjk1MTcxZjYzMTQ1ZmJhNzhhYjE1MmZjMzUwMDc2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYzE4N2ZhMWNiYWZiNDU3YjgyNDFiZTAxM2FlNGU3NDcgPSAkKCc8ZGl2IGlkPSJodG1sX2MxODdmYTFjYmFmYjQ1N2I4MjQxYmUwMTNhZTRlNzQ3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5NQk88L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FmMjk1MTcxZjYzMTQ1ZmJhNzhhYjE1MmZjMzUwMDc2LnNldENvbnRlbnQoaHRtbF9jMTg3ZmExY2JhZmI0NTdiODI0MWJlMDEzYWU0ZTc0Nyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzAyOTdmNTQxMjhjZjQzZGNiODhhMDhjMDIyMGYzZjYyLmJpbmRQb3B1cChwb3B1cF9hZjI5NTE3MWY2MzE0NWZiYTc4YWIxNTJmYzM1MDA3NikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzgyNGE0YTM5NGQzMjQzNzE5M2MyY2NmYmMyNGRlMTE1ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs3OC45MTU0LCAxMS45Mzg1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF81MmU3NzAwMDRjYmM0MzY1Yjc0NmEzODZiZjIwN2FjMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2IyMjVhMTM1OGM5ZTRiMjQ5N2YwZjBjMGYzYmMyMWM4ID0gJCgnPGRpdiBpZD0iaHRtbF9iMjI1YTEzNThjOWU0YjI0OTdmMGYwYzBmM2JjMjFjOCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+S0JTPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81MmU3NzAwMDRjYmM0MzY1Yjc0NmEzODZiZjIwN2FjMS5zZXRDb250ZW50KGh0bWxfYjIyNWExMzU4YzllNGIyNDk3ZjBmMGMwZjNiYzIxYzgpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84MjRhNGEzOTRkMzI0MzcxOTNjMmNjZmJjMjRkZTExNS5iaW5kUG9wdXAocG9wdXBfNTJlNzcwMDA0Y2JjNDM2NWI3NDZhMzg2YmYyMDdhYzEpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl85NzAxYTBiYzA0OTU0YjBkYWMwNmNhN2EzNjNjYmEwNCA9IEwubWFya2VyKAogICAgICAgICAgICBbLTEuMTI2OCwgMzcuMjUyM10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYWE5YmMxZDBkN2M1NDRmNzg3MTE0NmRmNzZiMDEyNjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yY2RhMDkwMjIwZDY0ZTM5YmM3ZmFiMDVkNjhjMzk5NiA9ICQoJzxkaXYgaWQ9Imh0bWxfMmNkYTA5MDIyMGQ2NGUzOWJjN2ZhYjA1ZDY4YzM5OTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPktNQk88L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FhOWJjMWQwZDdjNTQ0Zjc4NzExNDZkZjc2YjAxMjY0LnNldENvbnRlbnQoaHRtbF8yY2RhMDkwMjIwZDY0ZTM5YmM3ZmFiMDVkNjhjMzk5Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzk3MDFhMGJjMDQ5NTRiMGRhYzA2Y2E3YTM2M2NiYTA0LmJpbmRQb3B1cChwb3B1cF9hYTliYzFkMGQ3YzU0NGY3ODcxMTQ2ZGY3NmIwMTI2NCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzdhNGZlYTM3YTkyZTQwYjhhZDAxNzE2MmQ1NjMzNGZiID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs1LjIyODgsIDk2Ljk0NzJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzIyNmQ2ODNmY2Y0YTRmYmJiODAwMTI2MjAxYzhjZjc5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMjdmYWQxYTMwNmQwNDU4NmJiNTM1N2VlZmIyNWIwYjYgPSAkKCc8ZGl2IGlkPSJodG1sXzI3ZmFkMWEzMDZkMDQ1ODZiYjUzNTdlZWZiMjViMGI2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5MSE1JPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yMjZkNjgzZmNmNGE0ZmJiYjgwMDEyNjIwMWM4Y2Y3OS5zZXRDb250ZW50KGh0bWxfMjdmYWQxYTMwNmQwNDU4NmJiNTM1N2VlZmIyNWIwYjYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl83YTRmZWEzN2E5MmU0MGI4YWQwMTcxNjJkNTYzMzRmYi5iaW5kUG9wdXAocG9wdXBfMjI2ZDY4M2ZjZjRhNGZiYmI4MDAxMjYyMDFjOGNmNzkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9lMTNjNmRhNjNjZGM0NThlODA2NDVmMWUxZjBjZDY3NiA9IEwubWFya2VyKAogICAgICAgICAgICBbLTI2LjMzMDY2LCAtNTcuMzMwOTVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzJkNTc5ZjNjOGI1MTQ0YmNhYjMxNDI2MTNkNzdmN2VlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTUzZmM1YzFmNmYwNGRjMGEzODhjMDQzYmJiNDhlOGQgPSAkKCc8ZGl2IGlkPSJodG1sXzU1M2ZjNWMxZjZmMDRkYzBhMzg4YzA0M2JiYjQ4ZThkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5DUFVQPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8yZDU3OWYzYzhiNTE0NGJjYWIzMTQyNjEzZDc3ZjdlZS5zZXRDb250ZW50KGh0bWxfNTUzZmM1YzFmNmYwNGRjMGEzODhjMDQzYmJiNDhlOGQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9lMTNjNmRhNjNjZGM0NThlODA2NDVmMWUxZjBjZDY3Ni5iaW5kUG9wdXAocG9wdXBfMmQ1NzlmM2M4YjUxNDRiY2FiMzE0MjYxM2Q3N2Y3ZWUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80OGFkMTY0MjU4ZWE0OWUzYjNhZmExZmY1YWVjMDBjZiA9IEwubWFya2VyKAogICAgICAgICAgICBbNi42NzAxNiwgLTQuODU2NTZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhkZWI3ZDMzY2JhMDQ0YTZhNzJkYzg0OTkyZmZlYzA0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfN2YzOTJkOTAyYjk2NDc0MDk4Njc0YzRhN2JkNjg0NWIgPSAkKCc8ZGl2IGlkPSJodG1sXzdmMzkyZDkwMmI5NjQ3NDA5ODY3NGM0YTdiZDY4NDViIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5EQklDPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF84ZGViN2QzM2NiYTA0NGE2YTcyZGM4NDk5MmZmZWMwNC5zZXRDb250ZW50KGh0bWxfN2YzOTJkOTAyYjk2NDc0MDk4Njc0YzRhN2JkNjg0NWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80OGFkMTY0MjU4ZWE0OWUzYjNhZmExZmY1YWVjMDBjZi5iaW5kUG9wdXAocG9wdXBfOGRlYjdkMzNjYmEwNDRhNmE3MmRjODQ5OTJmZmVjMDQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zZGQyNTJiNjQ3ZjU0ZmRkOWRiOTFmN2I4NTlmZDM4OCA9IEwubWFya2VyKAogICAgICAgICAgICBbNDAuMDE4MywgMTE2LjE2NzldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZkNTYxNGMwYTA1YTRhNjA5OTA0NWVkMGEwOWYwNjk3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2I5YTNjNGJiNDY2NDVhYWFjNzA1NTZhYzhhNTg2YmMgPSAkKCc8ZGl2IGlkPSJodG1sXzNiOWEzYzRiYjQ2NjQ1YWFhYzcwNTU2YWM4YTU4NmJjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5CSlQ8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZkNTYxNGMwYTA1YTRhNjA5OTA0NWVkMGEwOWYwNjk3LnNldENvbnRlbnQoaHRtbF8zYjlhM2M0YmI0NjY0NWFhYWM3MDU1NmFjOGE1ODZiYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzNkZDI1MmI2NDdmNTRmZGQ5ZGI5MWY3Yjg1OWZkMzg4LmJpbmRQb3B1cChwb3B1cF82ZDU2MTRjMGEwNWE0YTYwOTkwNDVlZDBhMDlmMDY5NykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzg1NjEzMWUyNmZkMzQwZjM5ZjU4OWZlMjI3MWNmM2VjID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0OS4yNzA0LCAxMTkuNzQxNF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTYwMjhjZjA2MTA3NGJjMGFhMTQ3OTJkYzE1MWQ0YmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNGE3ODg0ZjQzM2E0YThkYmNjYTFiZjMyMDYwYjk0MyA9ICQoJzxkaXYgaWQ9Imh0bWxfMzRhNzg4NGY0MzNhNGE4ZGJjY2ExYmYzMjA2MGI5NDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkhJQTwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTYwMjhjZjA2MTA3NGJjMGFhMTQ3OTJkYzE1MWQ0YmUuc2V0Q29udGVudChodG1sXzM0YTc4ODRmNDMzYTRhOGRiY2NhMWJmMzIwNjBiOTQzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfODU2MTMxZTI2ZmQzNDBmMzlmNTg5ZmUyMjcxY2YzZWMuYmluZFBvcHVwKHBvcHVwX2E2MDI4Y2YwNjEwNzRiYzBhYTE0NzkyZGMxNTFkNGJlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZWZhM2M2YTRjNjdhNGI5MGJiOTY1ZDY1NzU2MjdjNzcgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI1LjEyMzMsIDEwMi43NF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZTY5YTU3MzU4NDQxNDRjY2JjOWJhNWYwMWE0NTg1NzggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lOTg4YTY4ZGE0YmY0ODIyYTk2ZGZjZWMwMDhjNmMzYiA9ICQoJzxkaXYgaWQ9Imh0bWxfZTk4OGE2OGRhNGJmNDgyMmE5NmRmY2VjMDA4YzZjM2IiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPktNSTwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZTY5YTU3MzU4NDQxNDRjY2JjOWJhNWYwMWE0NTg1Nzguc2V0Q29udGVudChodG1sX2U5ODhhNjhkYTRiZjQ4MjJhOTZkZmNlYzAwOGM2YzNiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZWZhM2M2YTRjNjdhNGI5MGJiOTY1ZDY1NzU2MjdjNzcuYmluZFBvcHVwKHBvcHVwX2U2OWE1NzM1ODQ0MTQ0Y2NiYzliYTVmMDFhNDU4NTc4KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfOWFhOGI3NTBkMjlkNGE4MmFjMTYxMDBmM2I5ZjMzZjYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE5LjAyOTEsIDEwOS44NDQ1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80NDI1ZTkzYjRmYzU0YzkyOWY2ZDkxZTA5MWJiNDgwNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzcyZmEwMDllMmQ1ZTQyNjQ4NzMxMjg4OWQ0MDg4NGE0ID0gJCgnPGRpdiBpZD0iaHRtbF83MmZhMDA5ZTJkNWU0MjY0ODczMTI4ODlkNDA4ODRhNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+UUlaPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80NDI1ZTkzYjRmYzU0YzkyOWY2ZDkxZTA5MWJiNDgwNy5zZXRDb250ZW50KGh0bWxfNzJmYTAwOWUyZDVlNDI2NDg3MzEyODg5ZDQwODg0YTQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl85YWE4Yjc1MGQyOWQ0YTgyYWMxNjEwMGYzYjlmMzNmNi5iaW5kUG9wdXAocG9wdXBfNDQyNWU5M2I0ZmM1NGM5MjlmNmQ5MWUwOTFiYjQ4MDcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8xMDAwYThlZTY2ODE0ZjMyYWFkNjQ1NWZiNmI3NzJiZSA9IEwubWFya2VyKAogICAgICAgICAgICBbMzEuMDk0OCwgMTIxLjE5MDhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzgwMGNkNzcwYjM3MTQ5ZjhhYWQwYzRmMzI4NjhlOTRhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2Q0Yjk3NWY5OWNkNDgwODk5YTRmMzQ2NDAwYWJiYzIgPSAkKCc8ZGl2IGlkPSJodG1sXzNkNGI5NzVmOTljZDQ4MDg5OWE0ZjM0NjQwMGFiYmMyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TU0U8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzgwMGNkNzcwYjM3MTQ5ZjhhYWQwYzRmMzI4NjhlOTRhLnNldENvbnRlbnQoaHRtbF8zZDRiOTc1Zjk5Y2Q0ODA4OTlhNGYzNDY0MDBhYmJjMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzEwMDBhOGVlNjY4MTRmMzJhYWQ2NDU1ZmI2Yjc3MmJlLmJpbmRQb3B1cChwb3B1cF84MDBjZDc3MGIzNzE0OWY4YWFkMGM0ZjMyODY4ZTk0YSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzQ2NzU2ZWI5NTYyODQxNGQ4MTE0MjNiNTAzNWJiN2VlID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0My44MTM4LCA4Ny43MDQ5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kY2U4NTNiMDgwY2I0YWVhYWNlZmYxY2YyNWZjNDYxMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzM3NTQ3OGJlZGIwOTQwYTRhOGMyZTZlZmE2NmY3OGRiID0gJCgnPGRpdiBpZD0iaHRtbF8zNzU0NzhiZWRiMDk0MGE0YThjMmU2ZWZhNjZmNzhkYiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+V01RPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kY2U4NTNiMDgwY2I0YWVhYWNlZmYxY2YyNWZjNDYxMC5zZXRDb250ZW50KGh0bWxfMzc1NDc4YmVkYjA5NDBhNGE4YzJlNmVmYTY2Zjc4ZGIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80Njc1NmViOTU2Mjg0MTRkODExNDIzYjUwMzViYjdlZS5iaW5kUG9wdXAocG9wdXBfZGNlODUzYjA4MGNiNGFlYWFjZWZmMWNmMjVmYzQ2MTApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9iMDZjODcwYmRmOGE0NjVjYTZhMmRiNWYwOWU3MmI3NiA9IEwubWFya2VyKAogICAgICAgICAgICBbMzQuMDMxMywgMTA4LjkyMzddLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQ3ODg3MTk2Y2M2OTRkZDQ5MGRlMmRhNjUyYmYzZTMyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTAwNDU0ZDQ1ZmQ2NGQxZDhhOTA5NGI2MjQ5Yzg2MmEgPSAkKCc8ZGl2IGlkPSJodG1sX2EwMDQ1NGQ0NWZkNjRkMWQ4YTkwOTRiNjI0OWM4NjJhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5YQU48L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQ3ODg3MTk2Y2M2OTRkZDQ5MGRlMmRhNjUyYmYzZTMyLnNldENvbnRlbnQoaHRtbF9hMDA0NTRkNDVmZDY0ZDFkOGE5MDk0YjYyNDljODYyYSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2IwNmM4NzBiZGY4YTQ2NWNhNmEyZGI1ZjA5ZTcyYjc2LmJpbmRQb3B1cChwb3B1cF80Nzg4NzE5NmNjNjk0ZGQ0OTBkZTJkYTY1MmJmM2UzMikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzY1NDc5NDJmMmEwZTQ2N2JhMmJmN2I4MTdiOTg3ZjA4ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0Mi42Mzc1LCA3NC40OTQyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wMzE2NWY0YTVkYmM0MTI2YTNhMDczODNlNWZiMzI1NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMzNWFhZDRlZTVlZjQ4NTM5YmRkNDZkMjE3NWE3OGUyID0gJCgnPGRpdiBpZD0iaHRtbF8zMzVhYWQ0ZWU1ZWY0ODUzOWJkZDQ2ZDIxNzVhNzhlMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUFLPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wMzE2NWY0YTVkYmM0MTI2YTNhMDczODNlNWZiMzI1Ny5zZXRDb250ZW50KGh0bWxfMzM1YWFkNGVlNWVmNDg1MzliZGQ0NmQyMTc1YTc4ZTIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82NTQ3OTQyZjJhMGU0NjdiYTJiZjdiODE3Yjk4N2YwOC5iaW5kUG9wdXAocG9wdXBfMDMxNjVmNGE1ZGJjNDEyNmEzYTA3MzgzZTVmYjMyNTcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zN2EzZWY1YjFiZmY0NDdhOTg0ZTNmZGVmZjZkMjI3YSA9IEwubWFya2VyKAogICAgICAgICAgICBbMzcuOTMwNCwgNTguMTE4OV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMjg3MTY2YTQ1ZjM3NDNiMTgwZjc2OGE2YzE3MGYzOTUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lZjZiM2JhMmU5ZWQ0MDA3OWFjMzUwMThhODFiMGE0YyA9ICQoJzxkaXYgaWQ9Imh0bWxfZWY2YjNiYTJlOWVkNDAwNzlhYzM1MDE4YTgxYjBhNGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkFCS1Q8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzI4NzE2NmE0NWYzNzQzYjE4MGY3NjhhNmMxNzBmMzk1LnNldENvbnRlbnQoaHRtbF9lZjZiM2JhMmU5ZWQ0MDA3OWFjMzUwMThhODFiMGE0Yyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzM3YTNlZjViMWJmZjQ0N2E5ODRlM2ZkZWZmNmQyMjdhLmJpbmRQb3B1cChwb3B1cF8yODcxNjZhNDVmMzc0M2IxODBmNzY4YTZjMTcwZjM5NSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzVmOTcwMzgwY2FlZTQ2NzhhOTM1MDk2YzE3MWY0ZGY1ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstMTkuMDE4LCA0Ny4yMjldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzkxMTIxMjFlMDAyZDQ5MTA4NGM3MTY1NWVlZGFiYTVlID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMWFlOTc4MWY2OTY0NDIyODk1ZTY1YmMyM2RiNGQ5YWQgPSAkKCc8ZGl2IGlkPSJodG1sXzFhZTk3ODFmNjk2NDQyMjg5NWU2NWJjMjNkYjRkOWFkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5BQlBPPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85MTEyMTIxZTAwMmQ0OTEwODRjNzE2NTVlZWRhYmE1ZS5zZXRDb250ZW50KGh0bWxfMWFlOTc4MWY2OTY0NDIyODk1ZTY1YmMyM2RiNGQ5YWQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl81Zjk3MDM4MGNhZWU0Njc4YTkzNTA5NmMxNzFmNGRmNS5iaW5kUG9wdXAocG9wdXBfOTExMjEyMWUwMDJkNDkxMDg0YzcxNjU1ZWVkYWJhNWUpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8yNGEyZjQ1YzIzNWU0ZWM1OWRhM2I1NWFkZDlmMmIxNyA9IEwubWFya2VyKAogICAgICAgICAgICBbODIuNTAzMywgLTYyLjM1XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80ZjhmMWU3YWMwNzE0YmJjOGNmMjMyZWVjZjk2M2Y3NyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzE4ODAzMGQxNzNiOTQwODE4MzA2YTJjNzYzYjI3YWM0ID0gJCgnPGRpdiBpZD0iaHRtbF8xODgwMzBkMTczYjk0MDgxODMwNmEyYzc2M2IyN2FjNCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QUxFPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80ZjhmMWU3YWMwNzE0YmJjOGNmMjMyZWVjZjk2M2Y3Ny5zZXRDb250ZW50KGh0bWxfMTg4MDMwZDE3M2I5NDA4MTgzMDZhMmM3NjNiMjdhYzQpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8yNGEyZjQ1YzIzNWU0ZWM1OWRhM2I1NWFkZDlmMmIxNy5iaW5kUG9wdXAocG9wdXBfNGY4ZjFlN2FjMDcxNGJiYzhjZjIzMmVlY2Y5NjNmNzcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9mN2I4ZjZjNThhMTE0YmZjOWVjMmNjYjI2Yjc2OTAyZiA9IEwubWFya2VyKAogICAgICAgICAgICBbNTYuNDMwMiwgNTguNTYyNV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDcwZTA0YWM1Zjk0NDExOWEyNmMzNTIyYmZiYTY5YTIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84NWU3ZDM4OTI0ZDM0YTdjODlkNTRhNTFiMjJiMjk0YyA9ICQoJzxkaXYgaWQ9Imh0bWxfODVlN2QzODkyNGQzNGE3Yzg5ZDU0YTUxYjIyYjI5NGMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkFSVTwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNDcwZTA0YWM1Zjk0NDExOWEyNmMzNTIyYmZiYTY5YTIuc2V0Q29udGVudChodG1sXzg1ZTdkMzg5MjRkMzRhN2M4OWQ1NGE1MWIyMmIyOTRjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZjdiOGY2YzU4YTExNGJmYzllYzJjY2IyNmI3NjkwMmYuYmluZFBvcHVwKHBvcHVwXzQ3MGUwNGFjNWY5NDQxMTlhMjZjMzUyMmJmYmE2OWEyKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMzRlZjk3NjA3N2QyNDBiY2JhZGYyYzg2N2IyYzQyNzAgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzU0LjcyNSwgLTEwMS45NzgzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9lODZiOTUyOGMxNWU0YzhiYjA5MDIyMjRlZjhmMTEwMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzMwMjYxMGI4ZDg5ZDQ4ZTNhZmViZGVmYmRmY2Q0ZmY2ID0gJCgnPGRpdiBpZD0iaHRtbF8zMDI2MTBiOGQ4OWQ0OGUzYWZlYmRlZmJkZmNkNGZmNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+RkZDPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lODZiOTUyOGMxNWU0YzhiYjA5MDIyMjRlZjhmMTEwMy5zZXRDb250ZW50KGh0bWxfMzAyNjEwYjhkODlkNDhlM2FmZWJkZWZiZGZjZDRmZjYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl8zNGVmOTc2MDc3ZDI0MGJjYmFkZjJjODY3YjJjNDI3MC5iaW5kUG9wdXAocG9wdXBfZTg2Yjk1MjhjMTVlNGM4YmIwOTAyMjI0ZWY4ZjExMDMpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9jYjllMGEwNjYyYmU0ZGJmOTdkODg3ZTc2NThjMDlhZCA9IEwubWFya2VyKAogICAgICAgICAgICBbMTAuMjkwOCwgLTg0Ljk1MjVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzdkMTc0MDA1NjFkMzQ2YzFiNjEzYWE5Nzk1YTQwMmNjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMzA5YTVkZjQ5ZTFiNGE1MWJmNDRhNmVkOTk4YmZmYWYgPSAkKCc8ZGl2IGlkPSJodG1sXzMwOWE1ZGY0OWUxYjRhNTFiZjQ0YTZlZDk5OGJmZmFmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5KVFM8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzdkMTc0MDA1NjFkMzQ2YzFiNjEzYWE5Nzk1YTQwMmNjLnNldENvbnRlbnQoaHRtbF8zMDlhNWRmNDllMWI0YTUxYmY0NGE2ZWQ5OThiZmZhZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2NiOWUwYTA2NjJiZTRkYmY5N2Q4ODdlNzY1OGMwOWFkLmJpbmRQb3B1cChwb3B1cF83ZDE3NDAwNTYxZDM0NmMxYjYxM2FhOTc5NWE0MDJjYykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzhjYWFhZDJjYjZiOTQxNjRiYmEwMjA1MGU5MDAzNjk0ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs1MC43MTU0LCA3OC42MjAyXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84YjNhYTE0YTQwZWU0NWNiYTE5YjUyMDdkODg3NjUzYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2NhNWJlMjA1Mjk3MTQ2MmM5MTNlNjg4MDgyZDAwNjMxID0gJCgnPGRpdiBpZD0iaHRtbF9jYTViZTIwNTI5NzE0NjJjOTEzZTY4ODA4MmQwMDYzMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+S1VSSzwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGIzYWExNGE0MGVlNDVjYmExOWI1MjA3ZDg4NzY1M2Euc2V0Q29udGVudChodG1sX2NhNWJlMjA1Mjk3MTQ2MmM5MTNlNjg4MDgyZDAwNjMxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfOGNhYWFkMmNiNmI5NDE2NGJiYTAyMDUwZTkwMDM2OTQuYmluZFBvcHVwKHBvcHVwXzhiM2FhMTRhNDBlZTQ1Y2JhMTliNTIwN2Q4ODc2NTNhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNDE3OGNjYTlkNTRlNDA3ZGIxZjA2Njc5YmJiYTAyZDQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWy00LjY3MzcsIDU1LjQ3OTJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Q4ZmExOTEzYmI1MjRjMjdiNjZlYzAyOTY1ZTNkNzA3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOGRhN2U1ODYwODk2NDNmMGE0ZTY3NzQzNTcxN2I5NTIgPSAkKCc8ZGl2IGlkPSJodG1sXzhkYTdlNTg2MDg5NjQzZjBhNGU2Nzc0MzU3MTdiOTUyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5NU0VZPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9kOGZhMTkxM2JiNTI0YzI3YjY2ZWMwMjk2NWUzZDcwNy5zZXRDb250ZW50KGh0bWxfOGRhN2U1ODYwODk2NDNmMGE0ZTY3NzQzNTcxN2I5NTIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80MTc4Y2NhOWQ1NGU0MDdkYjFmMDY2NzliYmJhMDJkNC5iaW5kUG9wdXAocG9wdXBfZDhmYTE5MTNiYjUyNGMyN2I2NmVjMDI5NjVlM2Q3MDcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80M2FmN2Q5OTRlMWM0MmIxYjViYWY1ZWY0MzEzNWI4ZCA9IEwubWFya2VyKAogICAgICAgICAgICBbNTEuNjgwNywgMTAzLjY0MzhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzBlNzdlNThlMzI3ZjQ1ZjliNWMxYzg5ZGE4MDNiNmIxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjE2ZjBmNWJlOThhNDE1OGIwNWU2ZTRlYmVkMmE4Y2MgPSAkKCc8ZGl2IGlkPSJodG1sX2YxNmYwZjViZTk4YTQxNThiMDVlNmU0ZWJlZDJhOGNjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5UTFk8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzBlNzdlNThlMzI3ZjQ1ZjliNWMxYzg5ZGE4MDNiNmIxLnNldENvbnRlbnQoaHRtbF9mMTZmMGY1YmU5OGE0MTU4YjA1ZTZlNGViZWQyYThjYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzQzYWY3ZDk5NGUxYzQyYjFiNWJhZjVlZjQzMTM1YjhkLmJpbmRQb3B1cChwb3B1cF8wZTc3ZTU4ZTMyN2Y0NWY5YjVjMWM4OWRhODAzYjZiMSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzBiMDk2NzY0M2MyNzQzNTVhYzRhZWY3MTFmM2JmMDExID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFszMi4zNzEzLCAtNjQuNjk2M10sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNmRlMTAwYjMzMWEwNGM5NWFkZWE3ZDEyYTM5MGRhNjkgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jZjMyNTNiZjkzYzc0YmM4YTY5Yzc3YWM5NWYxZTQ5NiA9ICQoJzxkaXYgaWQ9Imh0bWxfY2YzMjUzYmY5M2M3NGJjOGE2OWM3N2FjOTVmMWU0OTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkJCU1I8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzZkZTEwMGIzMzFhMDRjOTVhZGVhN2QxMmEzOTBkYTY5LnNldENvbnRlbnQoaHRtbF9jZjMyNTNiZjkzYzc0YmM4YTY5Yzc3YWM5NWYxZTQ5Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzBiMDk2NzY0M2MyNzQzNTVhYzRhZWY3MTFmM2JmMDExLmJpbmRQb3B1cChwb3B1cF82ZGUxMDBiMzMxYTA0Yzk1YWRlYTdkMTJhMzkwZGE2OSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzEzYmI4NWE1YjQxNTQ5ZDE4ODllODczMzdjY2M4ZDk2ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsxOC44MTQxLCA5OC45NDQzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mYjcxYjY5ZDZhNGQ0MmU0ODZlODgyOGVhN2YwZmNiOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzY1MDM3Yzk5NTZiYzRkZThiZDEzNzQ4NTJhZWQzYmRmID0gJCgnPGRpdiBpZD0iaHRtbF82NTAzN2M5OTU2YmM0ZGU4YmQxMzc0ODUyYWVkM2JkZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+Q0hUTzwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmI3MWI2OWQ2YTRkNDJlNDg2ZTg4MjhlYTdmMGZjYjkuc2V0Q29udGVudChodG1sXzY1MDM3Yzk5NTZiYzRkZThiZDEzNzQ4NTJhZWQzYmRmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMTNiYjg1YTViNDE1NDlkMTg4OWU4NzMzN2NjYzhkOTYuYmluZFBvcHVwKHBvcHVwX2ZiNzFiNjlkNmE0ZDQyZTQ4NmU4ODI4ZWE3ZjBmY2I5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfYTJmYzI3NzA4MWI5NGQ0Njg3YWNmNTg4MWMxNmFjMTYgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzQ0LjU4NTUsIC0xMjMuMzA0Nl0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzQwMDdiNWRhYjRhNGM0ZTg3MGVhODFlMzg5M2ZhZWIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hZDg0MTY1M2JlZDk0YTdhYTQ3NTdhMjU0NzdhNTAyZCA9ICQoJzxkaXYgaWQ9Imh0bWxfYWQ4NDE2NTNiZWQ5NGE3YWE0NzU3YTI1NDc3YTUwMmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkNPUjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzQwMDdiNWRhYjRhNGM0ZTg3MGVhODFlMzg5M2ZhZWIuc2V0Q29udGVudChodG1sX2FkODQxNjUzYmVkOTRhN2FhNDc1N2EyNTQ3N2E1MDJkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYTJmYzI3NzA4MWI5NGQ0Njg3YWNmNTg4MWMxNmFjMTYuYmluZFBvcHVwKHBvcHVwX2M0MDA3YjVkYWI0YTRjNGU4NzBlYTgxZTM4OTNmYWViKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNzcwYTM4ODc5ZjIxNDgxNGFiY2Q2MDI2MDM5MTNkOWMgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzI4LjExMDMsIC04MS40MzI3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iNjZlYTcxZjZiYjE0YmI3OTE1ZGVlYzA5NDg2YmNkOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc2Mjc5M2EyNTMzOTQ5ODNhNjEzYmU2ZDY4YmIwZWUyID0gJCgnPGRpdiBpZD0iaHRtbF83NjI3OTNhMjUzMzk0OTgzYTYxM2JlNmQ2OGJiMGVlMiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+RFdQRjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjY2ZWE3MWY2YmIxNGJiNzkxNWRlZWMwOTQ4NmJjZDkuc2V0Q29udGVudChodG1sXzc2Mjc5M2EyNTMzOTQ5ODNhNjEzYmU2ZDY4YmIwZWUyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNzcwYTM4ODc5ZjIxNDgxNGFiY2Q2MDI2MDM5MTNkOWMuYmluZFBvcHVwKHBvcHVwX2I2NmVhNzFmNmJiMTRiYjc5MTVkZWVjMDk0ODZiY2Q5KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfZGY2MzM2ZTkyOGY4NGRiYWExOWQ1NGY1MDgwNmY5M2QgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzM3LjQ3NzYsIDEyNi42MjM5XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kYWQwYThlYzJiMjI0NWY5YjZiNDY2YzcyNDU5OWZiMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzQxMTg2YzYxOWFjYzQ0OTlhYWI5NzE1ODhmMTc4YzlmID0gJCgnPGRpdiBpZD0iaHRtbF80MTE4NmM2MTlhY2M0NDk5YWFiOTcxNTg4ZjE3OGM5ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+SU5DTjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZGFkMGE4ZWMyYjIyNDVmOWI2YjQ2NmM3MjQ1OTlmYjAuc2V0Q29udGVudChodG1sXzQxMTg2YzYxOWFjYzQ0OTlhYWI5NzE1ODhmMTc4YzlmKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZGY2MzM2ZTkyOGY4NGRiYWExOWQ1NGY1MDgwNmY5M2QuYmluZFBvcHVwKHBvcHVwX2RhZDBhOGVjMmIyMjQ1ZjliNmI0NjZjNzI0NTk5ZmIwKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNjQxMjg4ZjJlYjRiNDU1ODkwMzQ5ZTcwMzAxYmFjNTQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzM0LjU0MDgsIDY5LjA0MzJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Y4OGUwYjE1MDhhNjQxMWZiOGRjMTc0ODA5MTE0ODk1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmFjMzc2N2RkYzRkNDA2NGEwOTI3NDNiYmIyOGUwZmYgPSAkKCc8ZGl2IGlkPSJodG1sX2ZhYzM3NjdkZGM0ZDQwNjRhMDkyNzQzYmJiMjhlMGZmIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5LQkw8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Y4OGUwYjE1MDhhNjQxMWZiOGRjMTc0ODA5MTE0ODk1LnNldENvbnRlbnQoaHRtbF9mYWMzNzY3ZGRjNGQ0MDY0YTA5Mjc0M2JiYjI4ZTBmZik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzY0MTI4OGYyZWI0YjQ1NTg5MDM0OWU3MDMwMWJhYzU0LmJpbmRQb3B1cChwb3B1cF9mODhlMGIxNTA4YTY0MTFmYjhkYzE3NDgwOTExNDg5NSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2FjYTE0YTU4MmU1ODQyNjBiYmZhMmQzMGEyMzUzZDkxID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstMTUuMjc3OSwgMjguMTg4Ml0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMDM3ZmFhN2U5ZjYwNDU0ZGIzYzA4ZGIzMWVlNzRiOGYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85NWE1ZGZkMDJmMzk0MWNiOTg4ZjNlZGU1ODJjOWQ5NCA9ICQoJzxkaXYgaWQ9Imh0bWxfOTVhNWRmZDAyZjM5NDFjYjk4OGYzZWRlNTgyYzlkOTQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkxTWjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMDM3ZmFhN2U5ZjYwNDU0ZGIzYzA4ZGIzMWVlNzRiOGYuc2V0Q29udGVudChodG1sXzk1YTVkZmQwMmYzOTQxY2I5ODhmM2VkZTU4MmM5ZDk0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYWNhMTRhNTgyZTU4NDI2MGJiZmEyZDMwYTIzNTNkOTEuYmluZFBvcHVwKHBvcHVwXzAzN2ZhYTdlOWY2MDQ1NGRiM2MwOGRiMzFlZTc0YjhmKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNmI4ODlhYzgwYmMwNDk3ZTgyYmMyMTg0ZGU5MDdlYmQgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzAuMjM3NiwgLTc4LjQ1MDhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E4MjdlZTNhZTBhZjRiODA5ZmNlMWU2OTNjZmRkNjc3ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOTY5NThkNGJmN2IyNDBhZWIwZTI2NjAyZWRlMzVhMDcgPSAkKCc8ZGl2IGlkPSJodG1sXzk2OTU4ZDRiZjdiMjQwYWViMGUyNjYwMmVkZTM1YTA3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5PVEFWPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9hODI3ZWUzYWUwYWY0YjgwOWZjZTFlNjkzY2ZkZDY3Ny5zZXRDb250ZW50KGh0bWxfOTY5NThkNGJmN2IyNDBhZWIwZTI2NjAyZWRlMzVhMDcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl82Yjg4OWFjODBiYzA0OTdlODJiYzIxODRkZTkwN2ViZC5iaW5kUG9wdXAocG9wdXBfYTgyN2VlM2FlMGFmNGI4MDlmY2UxZTY5M2NmZGQ2NzcpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl80NDY5Mzk0NTViZmI0ZTI5YmY4NWNjMjg2ZjdkMGNlNCA9IEwubWFya2VyKAogICAgICAgICAgICBbNTMuMDIzMywgMTU4LjY0OTldLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFlMzJmNjkzZmRlYjQwMjI5ODk5NzYyM2EzYzFlZmEzID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjNkNGNhNjI2MDk2NDgyZDhmZWViMDc4NTg4N2FjYTQgPSAkKCc8ZGl2IGlkPSJodG1sXzYzZDRjYTYyNjA5NjQ4MmQ4ZmVlYjA3ODU4ODdhY2E0IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5QRVQ8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzFlMzJmNjkzZmRlYjQwMjI5ODk5NzYyM2EzYzFlZmEzLnNldENvbnRlbnQoaHRtbF82M2Q0Y2E2MjYwOTY0ODJkOGZlZWIwNzg1ODg3YWNhNCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzQ0NjkzOTQ1NWJmYjRlMjliZjg1Y2MyODZmN2QwY2U0LmJpbmRQb3B1cChwb3B1cF8xZTMyZjY5M2ZkZWI0MDIyOTg5OTc2MjNhM2MxZWZhMykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzcwNjg1NTg5NTIzNTQ4NDA4ZTdmYzRiYTM5OTUyMDVhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstNS44Mjc0LCAtMzUuOTAxNF0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNTIxZjBiZGMyMDE4NGI5Njg5ZDAzZjhmMmMwYjdmOTMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hNDI3MWY4ODZkMzU0NWM1OWFlOTllZjNkZGQwMDAxOCA9ICQoJzxkaXYgaWQ9Imh0bWxfYTQyNzFmODg2ZDM1NDVjNTlhZTk5ZWYzZGRkMDAwMTgiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlJDQlI8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzUyMWYwYmRjMjAxODRiOTY4OWQwM2Y4ZjJjMGI3ZjkzLnNldENvbnRlbnQoaHRtbF9hNDI3MWY4ODZkMzU0NWM1OWFlOTllZjNkZGQwMDAxOCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzcwNjg1NTg5NTIzNTQ4NDA4ZTdmYzRiYTM5OTUyMDVhLmJpbmRQb3B1cChwb3B1cF81MjFmMGJkYzIwMTg0Yjk2ODlkMDNmOGYyYzBiN2Y5MykKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2M1MGNkYmY3NDM5YjRlMDhhMzA1MmMyNzNjMzU1MzhmID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFstOC45NDg5LCAtNjMuMTgzMV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOWJiYzlkMzdhMzQ0NDg1ODk0NWRkOWExNWIxNWExYzggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81NTUyYzVhZGM1MTc0ODQzODVkZThiOTc3MDBmYjZlOSA9ICQoJzxkaXYgaWQ9Imh0bWxfNTU1MmM1YWRjNTE3NDg0Mzg1ZGU4Yjk3NzAwZmI2ZTkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPlNBTUw8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzliYmM5ZDM3YTM0NDQ4NTg5NDVkZDlhMTViMTVhMWM4LnNldENvbnRlbnQoaHRtbF81NTUyYzVhZGM1MTc0ODQzODVkZThiOTc3MDBmYjZlOSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2M1MGNkYmY3NDM5YjRlMDhhMzA1MmMyNzNjMzU1MzhmLmJpbmRQb3B1cChwb3B1cF85YmJjOWQzN2EzNDQ0ODU4OTQ1ZGQ5YTE1YjE1YTFjOCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2Y1YjFkNzA1NWNmMDRkYTU5M2JiMmI3Mzc4NDg4ZWNjID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs4Ljg4MzksIC03MC42MzRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzljNmY3Yjg0MDI0ZjQxMWFiY2M3YzIyMmNmNjU5NTlmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZmFhM2I5NDNmM2ExNDQzNGI1OTY4NDZlNjZjMWQ3ZDEgPSAkKCc8ZGl2IGlkPSJodG1sX2ZhYTNiOTQzZjNhMTQ0MzRiNTk2ODQ2ZTY2YzFkN2QxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TRFY8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzljNmY3Yjg0MDI0ZjQxMWFiY2M3YzIyMmNmNjU5NTlmLnNldENvbnRlbnQoaHRtbF9mYWEzYjk0M2YzYTE0NDM0YjU5Njg0NmU2NmMxZDdkMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyX2Y1YjFkNzA1NWNmMDRkYTU5M2JiMmI3Mzc4NDg4ZWNjLmJpbmRQb3B1cChwb3B1cF85YzZmN2I4NDAyNGY0MTFhYmNjN2MyMjJjZjY1OTU5ZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2IxN2EwNGM5ZWYxYTQzMTlhMTdhYzdmZDE3ZmY4ODEyID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs2Ni45OTYxLCAtNTAuNjIwNzZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU5ZGZmZGM5YzllNzQ4Y2E5NmQ2ODNkMWQ3NDNmM2I5ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGRlMDMwMjQxODU5NDg5Y2E5ZjFlYzBlZGZkOGNlMzcgPSAkKCc8ZGl2IGlkPSJodG1sXzBkZTAzMDI0MTg1OTQ4OWNhOWYxZWMwZWRmZDhjZTM3IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TRkpEPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81OWRmZmRjOWM5ZTc0OGNhOTZkNjgzZDFkNzQzZjNiOS5zZXRDb250ZW50KGh0bWxfMGRlMDMwMjQxODU5NDg5Y2E5ZjFlYzBlZGZkOGNlMzcpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9iMTdhMDRjOWVmMWE0MzE5YTE3YWM3ZmQxN2ZmODgxMi5iaW5kUG9wdXAocG9wdXBfNTlkZmZkYzljOWU3NDhjYTk2ZDY4M2QxZDc0M2YzYjkpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kZTRiOThhMGE2MTc0NWRjYWE4NGM2ODNlZGQ2Y2ZmMyA9IEwubWFya2VyKAogICAgICAgICAgICBbNDAuNjM1OCwgLTc3Ljg4NzZdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2VjMjJkNjQ4YTk1NjRkNDY4ZThlZGU0MDQwZjBkMDQ4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTVhYmRjYzhkMDNiNDQzNDgzOWMxMTdjZDFiYjZiZmIgPSAkKCc8ZGl2IGlkPSJodG1sX2E1YWJkY2M4ZDAzYjQ0MzQ4MzljMTE3Y2QxYmI2YmZiIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5TU1BBPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9lYzIyZDY0OGE5NTY0ZDQ2OGU4ZWRlNDA0MGYwZDA0OC5zZXRDb250ZW50KGh0bWxfYTVhYmRjYzhkMDNiNDQzNDgzOWMxMTdjZDFiYjZiZmIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9kZTRiOThhMGE2MTc0NWRjYWE4NGM2ODNlZGQ2Y2ZmMy5iaW5kUG9wdXAocG9wdXBfZWMyMmQ2NDhhOTU2NGQ0NjhlOGVkZTQwNDBmMGQwNDgpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl9kZjI1ZGJmZDNlYWU0M2E1YmZlMGU4OGE3MTc5OGNlYiA9IEwubWFya2VyKAogICAgICAgICAgICBbMjAuMjI2MywgLTg4LjI3NjNdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzViZGI4MDkwOTNmMTRiODI4OTk2ZWY3OWIwNWM5NGMyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTllNTBjNGYwZjBlNDY3N2EwY2E0MmE3NTMzZjZkMTAgPSAkKCc8ZGl2IGlkPSJodG1sXzE5ZTUwYzRmMGYwZTQ2NzdhMGNhNDJhNzUzM2Y2ZDEwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5URUlHPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81YmRiODA5MDkzZjE0YjgyODk5NmVmNzliMDVjOTRjMi5zZXRDb250ZW50KGh0bWxfMTllNTBjNGYwZjBlNDY3N2EwY2E0MmE3NTMzZjZkMTApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl9kZjI1ZGJmZDNlYWU0M2E1YmZlMGU4OGE3MTc5OGNlYi5iaW5kUG9wdXAocG9wdXBfNWJkYjgwOTA5M2YxNGI4Mjg5OTZlZjc5YjA1Yzk0YzIpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl81M2IwMGE4NTExMzk0MjAzYjZjMDQzZDgxZWE0ZGRmNSA9IEwubWFya2VyKAogICAgICAgICAgICBbLTE5LjIwMjIsIDE3LjU4MzhdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzFiODkxY2ZlZjQxYzQ4YmNhMDkzMWNkYzdlZmZhMTFmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNTBmNDZhZTlhNGE2NDA2YmE3NjZmYWQyOGNmYjI3ZTAgPSAkKCc8ZGl2IGlkPSJodG1sXzUwZjQ2YWU5YTRhNjQwNmJhNzY2ZmFkMjhjZmIyN2UwIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5UU1VNPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xYjg5MWNmZWY0MWM0OGJjYTA5MzFjZGM3ZWZmYTExZi5zZXRDb250ZW50KGh0bWxfNTBmNDZhZTlhNGE2NDA2YmE3NjZmYWQyOGNmYjI3ZTApOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl81M2IwMGE4NTExMzk0MjAzYjZjMDQzZDgxZWE0ZGRmNS5iaW5kUG9wdXAocG9wdXBfMWI4OTFjZmVmNDFjNDhiY2EwOTMxY2RjN2VmZmExMWYpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8wNDMxYmJlYjgyNjI0Yjc0YTg1MjVkNDg4YmQwN2Q4MyA9IEwubWFya2VyKAogICAgICAgICAgICBbNDcuODY1MSwgMTA3LjA1MzJdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzRjY2UwYjdlYTE2MDRhOWJiZWRiMjk3ZGNlM2IwZWYwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMTRhMTYwMzE2NTA0NGFmYmI1OTc5YzQ4OTMwNzM0M2QgPSAkKCc8ZGl2IGlkPSJodG1sXzE0YTE2MDMxNjUwNDRhZmJiNTk3OWM0ODkzMDczNDNkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5VTE48L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRjY2UwYjdlYTE2MDRhOWJiZWRiMjk3ZGNlM2IwZWYwLnNldENvbnRlbnQoaHRtbF8xNGExNjAzMTY1MDQ0YWZiYjU5NzljNDg5MzA3MzQzZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzA0MzFiYmViODI2MjRiNzRhODUyNWQ0ODhiZDA3ZDgzLmJpbmRQb3B1cChwb3B1cF80Y2NlMGI3ZWExNjA0YTliYmVkYjI5N2RjZTNiMGVmMCkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2VhM2I2ZWJmNjY1NTRiNGU5YjA2OTQxYzkxZjJiMjE3ID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFszOC4yMjg5LCAtODYuMjkzOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfM2JlOTYwNDg4YWQxNGNlZGEyNTk0NDQ0YzA1NGNmMjcgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8yNDhiZjE4NzQ4NmQ0MzE5OTQ2NWFmODk5NDg5YmY2MCA9ICQoJzxkaXYgaWQ9Imh0bWxfMjQ4YmYxODc0ODZkNDMxOTk0NjVhZjg5OTQ4OWJmNjAiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPldDSTwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfM2JlOTYwNDg4YWQxNGNlZGEyNTk0NDQ0YzA1NGNmMjcuc2V0Q29udGVudChodG1sXzI0OGJmMTg3NDg2ZDQzMTk5NDY1YWY4OTk0ODliZjYwKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfZWEzYjZlYmY2NjU1NGI0ZTliMDY5NDFjOTFmMmIyMTcuYmluZFBvcHVwKHBvcHVwXzNiZTk2MDQ4OGFkMTRjZWRhMjU5NDQ0NGMwNTRjZjI3KQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMjlhY2M4N2NhZWVmNGI0NThmYTFlZWI5NjM4NGFiMjIgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzYyLjAzMSwgMTI5LjY4MDVdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhlNjVhNWM4MTE1ZjRhMzk4OGFjOTQyZjdmNTc0NDA2ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZTI4YTlhNjRhNzUxNGZmNWI0ZGM5ZTg4NWE0ZTE0N2QgPSAkKCc8ZGl2IGlkPSJodG1sX2UyOGE5YTY0YTc1MTRmZjViNGRjOWU4ODVhNGUxNDdkIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5ZQUs8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzhlNjVhNWM4MTE1ZjRhMzk4OGFjOTQyZjdmNTc0NDA2LnNldENvbnRlbnQoaHRtbF9lMjhhOWE2NGE3NTE0ZmY1YjRkYzllODg1YTRlMTQ3ZCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzI5YWNjODdjYWVlZjRiNDU4ZmExZWViOTYzODRhYjIyLmJpbmRQb3B1cChwb3B1cF84ZTY1YTVjODExNWY0YTM5ODhhYzk0MmY3ZjU3NDQwNikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzA2Y2FlYmNkNmViNDQ5NjM4NmNkYzRlYThhYzRiNDFiID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs0NC4xMTg4LCAxNDIuNTkzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82ZTQ5YjgyOTE0ZDM0ZTQ0ODI2Nzk2ZjNjZGU1OTM0MSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzdmYzNlNTBkZDkwNTQ4ZTFiMDYwZjQ3NDdiNjdkOGIxID0gJCgnPGRpdiBpZD0iaHRtbF83ZmMzZTUwZGQ5MDU0OGUxYjA2MGY0NzQ3YjY3ZDhiMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+QVNBSjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNmU0OWI4MjkxNGQzNGU0NDgyNjc5NmYzY2RlNTkzNDEuc2V0Q29udGVudChodG1sXzdmYzNlNTBkZDkwNTQ4ZTFiMDYwZjQ3NDdiNjdkOGIxKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfMDZjYWViY2Q2ZWI0NDk2Mzg2Y2RjNGVhOGFjNGI0MWIuYmluZFBvcHVwKHBvcHVwXzZlNDliODI5MTRkMzRlNDQ4MjY3OTZmM2NkZTU5MzQxKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNDMzMGJjY2I0OGEzNDFkYjk3OGFjYWY4Y2RkNmY4NjkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzUwLjQzNDgsIDU4LjAxNjRdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzMyM2JjNjIwMTA4MDQwNzBhNjdiODdjNmQ4YmQxMDgwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfM2RlYmJlMzkzMDZmNDNkNDliMDYxMTM0Mzk3Y2RiOTEgPSAkKCc8ZGl2IGlkPSJodG1sXzNkZWJiZTM5MzA2ZjQzZDQ5YjA2MTEzNDM5N2NkYjkxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5BS1RPPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8zMjNiYzYyMDEwODA0MDcwYTY3Yjg3YzZkOGJkMTA4MC5zZXRDb250ZW50KGh0bWxfM2RlYmJlMzkzMDZmNDNkNDliMDYxMTM0Mzk3Y2RiOTEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl80MzMwYmNjYjQ4YTM0MWRiOTc4YWNhZjhjZGQ2Zjg2OS5iaW5kUG9wdXAocG9wdXBfMzIzYmM2MjAxMDgwNDA3MGE2N2I4N2M2ZDhiZDEwODApCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgdmFyIG1hcmtlcl8zM2IxZGExZGVlODU0MWUzYWJjMzQ4NmM0MzUyMzkzMCA9IEwubWFya2VyKAogICAgICAgICAgICBbMS4zNjA4LCAxMDMuNzcyOV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMzYzMmMwYTAyM2I5NDY2YWExMWE0OTljZTE2OWYwYmYgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9hYTI4MWZiN2M0YTU0ODI5YTI3N2U1ZjU3ZGJmOGE0NiA9ICQoJzxkaXYgaWQ9Imh0bWxfYWEyODFmYjdjNGE1NDgyOWEyNzdlNWY1N2RiZjhhNDYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPkJUREY8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzM2MzJjMGEwMjNiOTQ2NmFhMTFhNDk5Y2UxNjlmMGJmLnNldENvbnRlbnQoaHRtbF9hYTI4MWZiN2M0YTU0ODI5YTI3N2U1ZjU3ZGJmOGE0Nik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzMzYjFkYTFkZWU4NTQxZTNhYmMzNDg2YzQzNTIzOTMwLmJpbmRQb3B1cChwb3B1cF8zNjMyYzBhMDIzYjk0NjZhYTExYTQ5OWNlMTY5ZjBiZikKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyX2IxZjJmNjFiYTZhYzQ0ZjQ5MTljYzczNTEzZTliMDVhID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFs3MC45ODY2LCAtOC41MDU3XSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8yNzliMjNkYWQ1M2E0MmU1YTM1YWUzOWVjYTcxNzFjYSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2Q1MjUzODI5NjQ5MTRhNzM5Y2ZmYzc0NWU2NmUyMGM5ID0gJCgnPGRpdiBpZD0iaHRtbF9kNTI1MzgyOTY0OTE0YTczOWNmZmM3NDVlNjZlMjBjOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+Sk1JQzwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMjc5YjIzZGFkNTNhNDJlNWEzNWFlMzllY2E3MTcxY2Euc2V0Q29udGVudChodG1sX2Q1MjUzODI5NjQ5MTRhNzM5Y2ZmYzc0NWU2NmUyMGM5KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfYjFmMmY2MWJhNmFjNDRmNDkxOWNjNzM1MTNlOWIwNWEuYmluZFBvcHVwKHBvcHVwXzI3OWIyM2RhZDUzYTQyZTVhMzVhZTM5ZWNhNzE3MWNhKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfNjEwMDdhOTg2YjMzNGExMGI2YjdiMTM2MWJkNWU2YzggPSBMLm1hcmtlcigKICAgICAgICAgICAgWzQ3Ljk0NjIsIC05MS40OTUzXSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWNvbjogbmV3IEwuSWNvbi5EZWZhdWx0KCkKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgKS5hZGRUbyhtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEpOwogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iMzE4NTY1OWFiZTM0NTBmOTVhMzk4ZGU2NDhiYjUxZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJwogICAgICAgICAgICAKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzUwOTk4MGE5MjE3YzQwYzRhZjRjZjdlZDMzNmIzYTM1ID0gJCgnPGRpdiBpZD0iaHRtbF81MDk5ODBhOTIxN2M0MGM0YWY0Y2Y3ZWQzMzZiM2EzNSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+PGI+RVlNTjwvYj48L2g0PjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYjMxODU2NTlhYmUzNDUwZjk1YTM5OGRlNjQ4YmI1MWUuc2V0Q29udGVudChodG1sXzUwOTk4MGE5MjE3YzQwYzRhZjRjZjdlZDMzNmIzYTM1KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBtYXJrZXJfNjEwMDdhOTg2YjMzNGExMGI2YjdiMTM2MWJkNWU2YzguYmluZFBvcHVwKHBvcHVwX2IzMTg1NjU5YWJlMzQ1MGY5NWEzOThkZTY0OGJiNTFlKQogICAgICAgICAgICA7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgIHZhciBtYXJrZXJfMmY4Mzg1YThmZTYyNDM5MWFkOWZkZGI5MzBjODJlMTkgPSBMLm1hcmtlcigKICAgICAgICAgICAgWzE0LjQ4NzI0LCA0OS4wMzc3OV0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGljb246IG5ldyBMLkljb24uRGVmYXVsdCgpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICkuYWRkVG8obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYTQ3MDQxYWNkZjRlNGE4YzlkMjgyOTJkMjY0YjU1MzUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCcKICAgICAgICAgICAgCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNmJlYTFhYWYzNmM0YTA1OTlmNzFhMWRjNmUxMTcwMyA9ICQoJzxkaXYgaWQ9Imh0bWxfYzZiZWExYWFmMzZjNGEwNTk5ZjcxYTFkYzZlMTE3MDMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjxiPk1VS0E8L2I+PC9oND48L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E0NzA0MWFjZGY0ZTRhOGM5ZDI4MjkyZDI2NGI1NTM1LnNldENvbnRlbnQoaHRtbF9jNmJlYTFhYWYzNmM0YTA1OTlmNzFhMWRjNmUxMTcwMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgbWFya2VyXzJmODM4NWE4ZmU2MjQzOTFhZDlmZGRiOTMwYzgyZTE5LmJpbmRQb3B1cChwb3B1cF9hNDcwNDFhY2RmNGU0YThjOWQyODI5MmQyNjRiNTUzNSkKICAgICAgICAgICAgOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICB2YXIgbWFya2VyXzgyMmMxNGEyMmFlZTQ1ZTFiZGJiYTEzOWU2ZjRkZDRlID0gTC5tYXJrZXIoCiAgICAgICAgICAgIFsxMy42MzUsIDM4Ljk4MTFdLAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpY29uOiBuZXcgTC5JY29uLkRlZmF1bHQoKQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApLmFkZFRvKG1hcF9lM2RmMGIzMDc4YWM0MDBhYTdmNDBiMzI1MWZiYjJiMSk7CiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzQyODllM2RlNGYyYTQ2OWZiZWQ4NWQ0ZTk3Mzg4YTc0ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnCiAgICAgICAgICAgIAogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYTg2Nzg2YzVlZGEwNDNmZTkzYTQxMmRiYmU2MmU2OTYgPSAkKCc8ZGl2IGlkPSJodG1sX2E4Njc4NmM1ZWRhMDQzZmU5M2E0MTJkYmJlNjJlNjk2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij48Yj5BRFlFPC9iPjwvaDQ+PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80Mjg5ZTNkZTRmMmE0NjlmYmVkODVkNGU5NzM4OGE3NC5zZXRDb250ZW50KGh0bWxfYTg2Nzg2YzVlZGEwNDNmZTkzYTQxMmRiYmU2MmU2OTYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIG1hcmtlcl84MjJjMTRhMjJhZWU0NWUxYmRiYmExMzllNmY0ZGQ0ZS5iaW5kUG9wdXAocG9wdXBfNDI4OWUzZGU0ZjJhNDY5ZmJlZDg1ZDRlOTczODhhNzQpCiAgICAgICAgICAgIDsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgICAgICB2YXIgbGF0X2xuZ19wb3B1cF84ODk5NzU3ZDk1OTg0ZTZkOGFkZGE0YTY2NmQxZGM5ZiA9IEwucG9wdXAoKTsKICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGxhdExuZ1BvcChlKSB7CiAgICAgICAgICAgICAgICAgICAgbGF0X2xuZ19wb3B1cF84ODk5NzU3ZDk1OTg0ZTZkOGFkZGE0YTY2NmQxZGM5ZgogICAgICAgICAgICAgICAgICAgICAgICAuc2V0TGF0TG5nKGUubGF0bG5nKQogICAgICAgICAgICAgICAgICAgICAgICAuc2V0Q29udGVudCgiTGF0aXR1ZGU6ICIgKyBlLmxhdGxuZy5sYXQudG9GaXhlZCg0KSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+TG9uZ2l0dWRlOiAiICsgZS5sYXRsbmcubG5nLnRvRml4ZWQoNCkpCiAgICAgICAgICAgICAgICAgICAgICAgIC5vcGVuT24obWFwX2UzZGYwYjMwNzhhYzQwMGFhN2Y0MGIzMjUxZmJiMmIxKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtYXBfZTNkZjBiMzA3OGFjNDAwYWE3ZjQwYjMyNTFmYmIyYjEub24oJ2NsaWNrJywgbGF0TG5nUG9wKTsKICAgICAgICAgICAgCjwvc2NyaXB0Pg==\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
  823. ],
  824. "text/plain": [
  825. "<folium.folium.Map at 0x7fc167b1d550>"
  826. ]
  827. },
  828. "execution_count": 16,
  829. "metadata": {},
  830. "output_type": "execute_result"
  831. }
  832. ],
  833. "source": [
  834. "def plot_stations():\n",
  835. " import folium\n",
  836. " fmap = folium.Map(\n",
  837. " location=[best_source.lat, best_source.lon],\n",
  838. " tiles='Stamen Terrain',\n",
  839. " zoom_start=3)\n",
  840. " folium.Marker([best_source.lat, best_source.lon],\n",
  841. " popup=('2009 Aquila Earthquake'),\n",
  842. " icon=folium.Icon(color='red', icon='info-sign')).add_to(fmap)\n",
  843. " \n",
  844. " for s in stations_list:\n",
  845. " folium.Marker([s.lat, s.lon],\n",
  846. " popup='<b>%s</b></h4>' % s.station).add_to(fmap)\n",
  847. " fmap.add_child(folium.LatLngPopup())\n",
  848. " return fmap\n",
  849. " \n",
  850. "plot_stations()"
  851. ]
  852. },
  853. {
  854. "cell_type": "code",
  855. "execution_count": 17,
  856. "metadata": {},
  857. "outputs": [
  858. {
  859. "data": {
  860. "application/javascript": [
  861. "/* Put everything inside the global mpl namespace */\n",
  862. "window.mpl = {};\n",
  863. "\n",
  864. "\n",
  865. "mpl.get_websocket_type = function() {\n",
  866. " if (typeof(WebSocket) !== 'undefined') {\n",
  867. " return WebSocket;\n",
  868. " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
  869. " return MozWebSocket;\n",
  870. " } else {\n",
  871. " alert('Your browser does not have WebSocket support.' +\n",
  872. " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
  873. " 'Firefox 4 and 5 are also supported but you ' +\n",
  874. " 'have to enable WebSockets in about:config.');\n",
  875. " };\n",
  876. "}\n",
  877. "\n",
  878. "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
  879. " this.id = figure_id;\n",
  880. "\n",
  881. " this.ws = websocket;\n",
  882. "\n",
  883. " this.supports_binary = (this.ws.binaryType != undefined);\n",
  884. "\n",
  885. " if (!this.supports_binary) {\n",
  886. " var warnings = document.getElementById(\"mpl-warnings\");\n",
  887. " if (warnings) {\n",
  888. " warnings.style.display = 'block';\n",
  889. " warnings.textContent = (\n",
  890. " \"This browser does not support binary websocket messages. \" +\n",
  891. " \"Performance may be slow.\");\n",
  892. " }\n",
  893. " }\n",
  894. "\n",
  895. " this.imageObj = new Image();\n",
  896. "\n",
  897. " this.context = undefined;\n",
  898. " this.message = undefined;\n",
  899. " this.canvas = undefined;\n",
  900. " this.rubberband_canvas = undefined;\n",
  901. " this.rubberband_context = undefined;\n",
  902. " this.format_dropdown = undefined;\n",
  903. "\n",
  904. " this.image_mode = 'full';\n",
  905. "\n",
  906. " this.root = $('<div/>');\n",
  907. " this._root_extra_style(this.root)\n",
  908. " this.root.attr('style', 'display: inline-block');\n",
  909. "\n",
  910. " $(parent_element).append(this.root);\n",
  911. "\n",
  912. " this._init_header(this);\n",
  913. " this._init_canvas(this);\n",
  914. " this._init_toolbar(this);\n",
  915. "\n",
  916. " var fig = this;\n",
  917. "\n",
  918. " this.waiting = false;\n",
  919. "\n",
  920. " this.ws.onopen = function () {\n",
  921. " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
  922. " fig.send_message(\"send_image_mode\", {});\n",
  923. " if (mpl.ratio != 1) {\n",
  924. " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
  925. " }\n",
  926. " fig.send_message(\"refresh\", {});\n",
  927. " }\n",
  928. "\n",
  929. " this.imageObj.onload = function() {\n",
  930. " if (fig.image_mode == 'full') {\n",
  931. " // Full images could contain transparency (where diff images\n",
  932. " // almost always do), so we need to clear the canvas so that\n",
  933. " // there is no ghosting.\n",
  934. " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
  935. " }\n",
  936. " fig.context.drawImage(fig.imageObj, 0, 0);\n",
  937. " };\n",
  938. "\n",
  939. " this.imageObj.onunload = function() {\n",
  940. " fig.ws.close();\n",
  941. " }\n",
  942. "\n",
  943. " this.ws.onmessage = this._make_on_message_function(this);\n",
  944. "\n",
  945. " this.ondownload = ondownload;\n",
  946. "}\n",
  947. "\n",
  948. "mpl.figure.prototype._init_header = function() {\n",
  949. " var titlebar = $(\n",
  950. " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
  951. " 'ui-helper-clearfix\"/>');\n",
  952. " var titletext = $(\n",
  953. " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
  954. " 'text-align: center; padding: 3px;\"/>');\n",
  955. " titlebar.append(titletext)\n",
  956. " this.root.append(titlebar);\n",
  957. " this.header = titletext[0];\n",
  958. "}\n",
  959. "\n",
  960. "\n",
  961. "\n",
  962. "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
  963. "\n",
  964. "}\n",
  965. "\n",
  966. "\n",
  967. "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
  968. "\n",
  969. "}\n",
  970. "\n",
  971. "mpl.figure.prototype._init_canvas = function() {\n",
  972. " var fig = this;\n",
  973. "\n",
  974. " var canvas_div = $('<div/>');\n",
  975. "\n",
  976. " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
  977. "\n",
  978. " function canvas_keyboard_event(event) {\n",
  979. " return fig.key_event(event, event['data']);\n",
  980. " }\n",
  981. "\n",
  982. " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
  983. " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
  984. " this.canvas_div = canvas_div\n",
  985. " this._canvas_extra_style(canvas_div)\n",
  986. " this.root.append(canvas_div);\n",
  987. "\n",
  988. " var canvas = $('<canvas/>');\n",
  989. " canvas.addClass('mpl-canvas');\n",
  990. " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
  991. "\n",
  992. " this.canvas = canvas[0];\n",
  993. " this.context = canvas[0].getContext(\"2d\");\n",
  994. "\n",
  995. " var backingStore = this.context.backingStorePixelRatio ||\n",
  996. "\tthis.context.webkitBackingStorePixelRatio ||\n",
  997. "\tthis.context.mozBackingStorePixelRatio ||\n",
  998. "\tthis.context.msBackingStorePixelRatio ||\n",
  999. "\tthis.context.oBackingStorePixelRatio ||\n",
  1000. "\tthis.context.backingStorePixelRatio || 1;\n",
  1001. "\n",
  1002. " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
  1003. "\n",
  1004. " var rubberband = $('<canvas/>');\n",
  1005. " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
  1006. "\n",
  1007. " var pass_mouse_events = true;\n",
  1008. "\n",
  1009. " canvas_div.resizable({\n",
  1010. " start: function(event, ui) {\n",
  1011. " pass_mouse_events = false;\n",
  1012. " },\n",
  1013. " resize: function(event, ui) {\n",
  1014. " fig.request_resize(ui.size.width, ui.size.height);\n",
  1015. " },\n",
  1016. " stop: function(event, ui) {\n",
  1017. " pass_mouse_events = true;\n",
  1018. " fig.request_resize(ui.size.width, ui.size.height);\n",
  1019. " },\n",
  1020. " });\n",
  1021. "\n",
  1022. " function mouse_event_fn(event) {\n",
  1023. " if (pass_mouse_events)\n",
  1024. " return fig.mouse_event(event, event['data']);\n",
  1025. " }\n",
  1026. "\n",
  1027. " rubberband.mousedown('button_press', mouse_event_fn);\n",
  1028. " rubberband.mouseup('button_release', mouse_event_fn);\n",
  1029. " // Throttle sequential mouse events to 1 every 20ms.\n",
  1030. " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
  1031. "\n",
  1032. " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
  1033. " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
  1034. "\n",
  1035. " canvas_div.on(\"wheel\", function (event) {\n",
  1036. " event = event.originalEvent;\n",
  1037. " event['data'] = 'scroll'\n",
  1038. " if (event.deltaY < 0) {\n",
  1039. " event.step = 1;\n",
  1040. " } else {\n",
  1041. " event.step = -1;\n",
  1042. " }\n",
  1043. " mouse_event_fn(event);\n",
  1044. " });\n",
  1045. "\n",
  1046. " canvas_div.append(canvas);\n",
  1047. " canvas_div.append(rubberband);\n",
  1048. "\n",
  1049. " this.rubberband = rubberband;\n",
  1050. " this.rubberband_canvas = rubberband[0];\n",
  1051. " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
  1052. " this.rubberband_context.strokeStyle = \"#000000\";\n",
  1053. "\n",
  1054. " this._resize_canvas = function(width, height) {\n",
  1055. " // Keep the size of the canvas, canvas container, and rubber band\n",
  1056. " // canvas in synch.\n",
  1057. " canvas_div.css('width', width)\n",
  1058. " canvas_div.css('height', height)\n",
  1059. "\n",
  1060. " canvas.attr('width', width * mpl.ratio);\n",
  1061. " canvas.attr('height', height * mpl.ratio);\n",
  1062. " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
  1063. "\n",
  1064. " rubberband.attr('width', width);\n",
  1065. " rubberband.attr('height', height);\n",
  1066. " }\n",
  1067. "\n",
  1068. " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
  1069. " // upon first draw.\n",
  1070. " this._resize_canvas(600, 600);\n",
  1071. "\n",
  1072. " // Disable right mouse context menu.\n",
  1073. " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
  1074. " return false;\n",
  1075. " });\n",
  1076. "\n",
  1077. " function set_focus () {\n",
  1078. " canvas.focus();\n",
  1079. " canvas_div.focus();\n",
  1080. " }\n",
  1081. "\n",
  1082. " window.setTimeout(set_focus, 100);\n",
  1083. "}\n",
  1084. "\n",
  1085. "mpl.figure.prototype._init_toolbar = function() {\n",
  1086. " var fig = this;\n",
  1087. "\n",
  1088. " var nav_element = $('<div/>')\n",
  1089. " nav_element.attr('style', 'width: 100%');\n",
  1090. " this.root.append(nav_element);\n",
  1091. "\n",
  1092. " // Define a callback function for later on.\n",
  1093. " function toolbar_event(event) {\n",
  1094. " return fig.toolbar_button_onclick(event['data']);\n",
  1095. " }\n",
  1096. " function toolbar_mouse_event(event) {\n",
  1097. " return fig.toolbar_button_onmouseover(event['data']);\n",
  1098. " }\n",
  1099. "\n",
  1100. " for(var toolbar_ind in mpl.toolbar_items) {\n",
  1101. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  1102. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  1103. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  1104. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  1105. "\n",
  1106. " if (!name) {\n",
  1107. " // put a spacer in here.\n",
  1108. " continue;\n",
  1109. " }\n",
  1110. " var button = $('<button/>');\n",
  1111. " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
  1112. " 'ui-button-icon-only');\n",
  1113. " button.attr('role', 'button');\n",
  1114. " button.attr('aria-disabled', 'false');\n",
  1115. " button.click(method_name, toolbar_event);\n",
  1116. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  1117. "\n",
  1118. " var icon_img = $('<span/>');\n",
  1119. " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
  1120. " icon_img.addClass(image);\n",
  1121. " icon_img.addClass('ui-corner-all');\n",
  1122. "\n",
  1123. " var tooltip_span = $('<span/>');\n",
  1124. " tooltip_span.addClass('ui-button-text');\n",
  1125. " tooltip_span.html(tooltip);\n",
  1126. "\n",
  1127. " button.append(icon_img);\n",
  1128. " button.append(tooltip_span);\n",
  1129. "\n",
  1130. " nav_element.append(button);\n",
  1131. " }\n",
  1132. "\n",
  1133. " var fmt_picker_span = $('<span/>');\n",
  1134. "\n",
  1135. " var fmt_picker = $('<select/>');\n",
  1136. " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
  1137. " fmt_picker_span.append(fmt_picker);\n",
  1138. " nav_element.append(fmt_picker_span);\n",
  1139. " this.format_dropdown = fmt_picker[0];\n",
  1140. "\n",
  1141. " for (var ind in mpl.extensions) {\n",
  1142. " var fmt = mpl.extensions[ind];\n",
  1143. " var option = $(\n",
  1144. " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
  1145. " fmt_picker.append(option)\n",
  1146. " }\n",
  1147. "\n",
  1148. " // Add hover states to the ui-buttons\n",
  1149. " $( \".ui-button\" ).hover(\n",
  1150. " function() { $(this).addClass(\"ui-state-hover\");},\n",
  1151. " function() { $(this).removeClass(\"ui-state-hover\");}\n",
  1152. " );\n",
  1153. "\n",
  1154. " var status_bar = $('<span class=\"mpl-message\"/>');\n",
  1155. " nav_element.append(status_bar);\n",
  1156. " this.message = status_bar[0];\n",
  1157. "}\n",
  1158. "\n",
  1159. "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
  1160. " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
  1161. " // which will in turn request a refresh of the image.\n",
  1162. " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
  1163. "}\n",
  1164. "\n",
  1165. "mpl.figure.prototype.send_message = function(type, properties) {\n",
  1166. " properties['type'] = type;\n",
  1167. " properties['figure_id'] = this.id;\n",
  1168. " this.ws.send(JSON.stringify(properties));\n",
  1169. "}\n",
  1170. "\n",
  1171. "mpl.figure.prototype.send_draw_message = function() {\n",
  1172. " if (!this.waiting) {\n",
  1173. " this.waiting = true;\n",
  1174. " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
  1175. " }\n",
  1176. "}\n",
  1177. "\n",
  1178. "\n",
  1179. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  1180. " var format_dropdown = fig.format_dropdown;\n",
  1181. " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
  1182. " fig.ondownload(fig, format);\n",
  1183. "}\n",
  1184. "\n",
  1185. "\n",
  1186. "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
  1187. " var size = msg['size'];\n",
  1188. " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
  1189. " fig._resize_canvas(size[0], size[1]);\n",
  1190. " fig.send_message(\"refresh\", {});\n",
  1191. " };\n",
  1192. "}\n",
  1193. "\n",
  1194. "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
  1195. " var x0 = msg['x0'] / mpl.ratio;\n",
  1196. " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
  1197. " var x1 = msg['x1'] / mpl.ratio;\n",
  1198. " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
  1199. " x0 = Math.floor(x0) + 0.5;\n",
  1200. " y0 = Math.floor(y0) + 0.5;\n",
  1201. " x1 = Math.floor(x1) + 0.5;\n",
  1202. " y1 = Math.floor(y1) + 0.5;\n",
  1203. " var min_x = Math.min(x0, x1);\n",
  1204. " var min_y = Math.min(y0, y1);\n",
  1205. " var width = Math.abs(x1 - x0);\n",
  1206. " var height = Math.abs(y1 - y0);\n",
  1207. "\n",
  1208. " fig.rubberband_context.clearRect(\n",
  1209. " 0, 0, fig.canvas.width, fig.canvas.height);\n",
  1210. "\n",
  1211. " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
  1212. "}\n",
  1213. "\n",
  1214. "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
  1215. " // Updates the figure title.\n",
  1216. " fig.header.textContent = msg['label'];\n",
  1217. "}\n",
  1218. "\n",
  1219. "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
  1220. " var cursor = msg['cursor'];\n",
  1221. " switch(cursor)\n",
  1222. " {\n",
  1223. " case 0:\n",
  1224. " cursor = 'pointer';\n",
  1225. " break;\n",
  1226. " case 1:\n",
  1227. " cursor = 'default';\n",
  1228. " break;\n",
  1229. " case 2:\n",
  1230. " cursor = 'crosshair';\n",
  1231. " break;\n",
  1232. " case 3:\n",
  1233. " cursor = 'move';\n",
  1234. " break;\n",
  1235. " }\n",
  1236. " fig.rubberband_canvas.style.cursor = cursor;\n",
  1237. "}\n",
  1238. "\n",
  1239. "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
  1240. " fig.message.textContent = msg['message'];\n",
  1241. "}\n",
  1242. "\n",
  1243. "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
  1244. " // Request the server to send over a new figure.\n",
  1245. " fig.send_draw_message();\n",
  1246. "}\n",
  1247. "\n",
  1248. "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
  1249. " fig.image_mode = msg['mode'];\n",
  1250. "}\n",
  1251. "\n",
  1252. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  1253. " // Called whenever the canvas gets updated.\n",
  1254. " this.send_message(\"ack\", {});\n",
  1255. "}\n",
  1256. "\n",
  1257. "// A function to construct a web socket function for onmessage handling.\n",
  1258. "// Called in the figure constructor.\n",
  1259. "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
  1260. " return function socket_on_message(evt) {\n",
  1261. " if (evt.data instanceof Blob) {\n",
  1262. " /* FIXME: We get \"Resource interpreted as Image but\n",
  1263. " * transferred with MIME type text/plain:\" errors on\n",
  1264. " * Chrome. But how to set the MIME type? It doesn't seem\n",
  1265. " * to be part of the websocket stream */\n",
  1266. " evt.data.type = \"image/png\";\n",
  1267. "\n",
  1268. " /* Free the memory for the previous frames */\n",
  1269. " if (fig.imageObj.src) {\n",
  1270. " (window.URL || window.webkitURL).revokeObjectURL(\n",
  1271. " fig.imageObj.src);\n",
  1272. " }\n",
  1273. "\n",
  1274. " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
  1275. " evt.data);\n",
  1276. " fig.updated_canvas_event();\n",
  1277. " fig.waiting = false;\n",
  1278. " return;\n",
  1279. " }\n",
  1280. " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
  1281. " fig.imageObj.src = evt.data;\n",
  1282. " fig.updated_canvas_event();\n",
  1283. " fig.waiting = false;\n",
  1284. " return;\n",
  1285. " }\n",
  1286. "\n",
  1287. " var msg = JSON.parse(evt.data);\n",
  1288. " var msg_type = msg['type'];\n",
  1289. "\n",
  1290. " // Call the \"handle_{type}\" callback, which takes\n",
  1291. " // the figure and JSON message as its only arguments.\n",
  1292. " try {\n",
  1293. " var callback = fig[\"handle_\" + msg_type];\n",
  1294. " } catch (e) {\n",
  1295. " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
  1296. " return;\n",
  1297. " }\n",
  1298. "\n",
  1299. " if (callback) {\n",
  1300. " try {\n",
  1301. " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
  1302. " callback(fig, msg);\n",
  1303. " } catch (e) {\n",
  1304. " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
  1305. " }\n",
  1306. " }\n",
  1307. " };\n",
  1308. "}\n",
  1309. "\n",
  1310. "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
  1311. "mpl.findpos = function(e) {\n",
  1312. " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
  1313. " var targ;\n",
  1314. " if (!e)\n",
  1315. " e = window.event;\n",
  1316. " if (e.target)\n",
  1317. " targ = e.target;\n",
  1318. " else if (e.srcElement)\n",
  1319. " targ = e.srcElement;\n",
  1320. " if (targ.nodeType == 3) // defeat Safari bug\n",
  1321. " targ = targ.parentNode;\n",
  1322. "\n",
  1323. " // jQuery normalizes the pageX and pageY\n",
  1324. " // pageX,Y are the mouse positions relative to the document\n",
  1325. " // offset() returns the position of the element relative to the document\n",
  1326. " var x = e.pageX - $(targ).offset().left;\n",
  1327. " var y = e.pageY - $(targ).offset().top;\n",
  1328. "\n",
  1329. " return {\"x\": x, \"y\": y};\n",
  1330. "};\n",
  1331. "\n",
  1332. "/*\n",
  1333. " * return a copy of an object with only non-object keys\n",
  1334. " * we need this to avoid circular references\n",
  1335. " * http://stackoverflow.com/a/24161582/3208463\n",
  1336. " */\n",
  1337. "function simpleKeys (original) {\n",
  1338. " return Object.keys(original).reduce(function (obj, key) {\n",
  1339. " if (typeof original[key] !== 'object')\n",
  1340. " obj[key] = original[key]\n",
  1341. " return obj;\n",
  1342. " }, {});\n",
  1343. "}\n",
  1344. "\n",
  1345. "mpl.figure.prototype.mouse_event = function(event, name) {\n",
  1346. " var canvas_pos = mpl.findpos(event)\n",
  1347. "\n",
  1348. " if (name === 'button_press')\n",
  1349. " {\n",
  1350. " this.canvas.focus();\n",
  1351. " this.canvas_div.focus();\n",
  1352. " }\n",
  1353. "\n",
  1354. " var x = canvas_pos.x * mpl.ratio;\n",
  1355. " var y = canvas_pos.y * mpl.ratio;\n",
  1356. "\n",
  1357. " this.send_message(name, {x: x, y: y, button: event.button,\n",
  1358. " step: event.step,\n",
  1359. " guiEvent: simpleKeys(event)});\n",
  1360. "\n",
  1361. " /* This prevents the web browser from automatically changing to\n",
  1362. " * the text insertion cursor when the button is pressed. We want\n",
  1363. " * to control all of the cursor setting manually through the\n",
  1364. " * 'cursor' event from matplotlib */\n",
  1365. " event.preventDefault();\n",
  1366. " return false;\n",
  1367. "}\n",
  1368. "\n",
  1369. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  1370. " // Handle any extra behaviour associated with a key event\n",
  1371. "}\n",
  1372. "\n",
  1373. "mpl.figure.prototype.key_event = function(event, name) {\n",
  1374. "\n",
  1375. " // Prevent repeat events\n",
  1376. " if (name == 'key_press')\n",
  1377. " {\n",
  1378. " if (event.which === this._key)\n",
  1379. " return;\n",
  1380. " else\n",
  1381. " this._key = event.which;\n",
  1382. " }\n",
  1383. " if (name == 'key_release')\n",
  1384. " this._key = null;\n",
  1385. "\n",
  1386. " var value = '';\n",
  1387. " if (event.ctrlKey && event.which != 17)\n",
  1388. " value += \"ctrl+\";\n",
  1389. " if (event.altKey && event.which != 18)\n",
  1390. " value += \"alt+\";\n",
  1391. " if (event.shiftKey && event.which != 16)\n",
  1392. " value += \"shift+\";\n",
  1393. "\n",
  1394. " value += 'k';\n",
  1395. " value += event.which.toString();\n",
  1396. "\n",
  1397. " this._key_event_extra(event, name);\n",
  1398. "\n",
  1399. " this.send_message(name, {key: value,\n",
  1400. " guiEvent: simpleKeys(event)});\n",
  1401. " return false;\n",
  1402. "}\n",
  1403. "\n",
  1404. "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
  1405. " if (name == 'download') {\n",
  1406. " this.handle_save(this, null);\n",
  1407. " } else {\n",
  1408. " this.send_message(\"toolbar_button\", {name: name});\n",
  1409. " }\n",
  1410. "};\n",
  1411. "\n",
  1412. "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
  1413. " this.message.textContent = tooltip;\n",
  1414. "};\n",
  1415. "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
  1416. "\n",
  1417. "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
  1418. "\n",
  1419. "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
  1420. " // Create a \"websocket\"-like object which calls the given IPython comm\n",
  1421. " // object with the appropriate methods. Currently this is a non binary\n",
  1422. " // socket, so there is still some room for performance tuning.\n",
  1423. " var ws = {};\n",
  1424. "\n",
  1425. " ws.close = function() {\n",
  1426. " comm.close()\n",
  1427. " };\n",
  1428. " ws.send = function(m) {\n",
  1429. " //console.log('sending', m);\n",
  1430. " comm.send(m);\n",
  1431. " };\n",
  1432. " // Register the callback with on_msg.\n",
  1433. " comm.on_msg(function(msg) {\n",
  1434. " //console.log('receiving', msg['content']['data'], msg);\n",
  1435. " // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
  1436. " ws.onmessage(msg['content']['data'])\n",
  1437. " });\n",
  1438. " return ws;\n",
  1439. "}\n",
  1440. "\n",
  1441. "mpl.mpl_figure_comm = function(comm, msg) {\n",
  1442. " // This is the function which gets called when the mpl process\n",
  1443. " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
  1444. "\n",
  1445. " var id = msg.content.data.id;\n",
  1446. " // Get hold of the div created by the display call when the Comm\n",
  1447. " // socket was opened in Python.\n",
  1448. " var element = $(\"#\" + id);\n",
  1449. " var ws_proxy = comm_websocket_adapter(comm)\n",
  1450. "\n",
  1451. " function ondownload(figure, format) {\n",
  1452. " window.open(figure.imageObj.src);\n",
  1453. " }\n",
  1454. "\n",
  1455. " var fig = new mpl.figure(id, ws_proxy,\n",
  1456. " ondownload,\n",
  1457. " element.get(0));\n",
  1458. "\n",
  1459. " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
  1460. " // web socket which is closed, not our websocket->open comm proxy.\n",
  1461. " ws_proxy.onopen();\n",
  1462. "\n",
  1463. " fig.parent_element = element.get(0);\n",
  1464. " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
  1465. " if (!fig.cell_info) {\n",
  1466. " console.error(\"Failed to find cell for figure\", id, fig);\n",
  1467. " return;\n",
  1468. " }\n",
  1469. "\n",
  1470. " var output_index = fig.cell_info[2]\n",
  1471. " var cell = fig.cell_info[0];\n",
  1472. "\n",
  1473. "};\n",
  1474. "\n",
  1475. "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
  1476. " var width = fig.canvas.width/mpl.ratio\n",
  1477. " fig.root.unbind('remove')\n",
  1478. "\n",
  1479. " // Update the output cell to use the data from the current canvas.\n",
  1480. " fig.push_to_output();\n",
  1481. " var dataURL = fig.canvas.toDataURL();\n",
  1482. " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
  1483. " // the notebook keyboard shortcuts fail.\n",
  1484. " IPython.keyboard_manager.enable()\n",
  1485. " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
  1486. " fig.close_ws(fig, msg);\n",
  1487. "}\n",
  1488. "\n",
  1489. "mpl.figure.prototype.close_ws = function(fig, msg){\n",
  1490. " fig.send_message('closing', msg);\n",
  1491. " // fig.ws.close()\n",
  1492. "}\n",
  1493. "\n",
  1494. "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
  1495. " // Turn the data on the canvas into data in the output cell.\n",
  1496. " var width = this.canvas.width/mpl.ratio\n",
  1497. " var dataURL = this.canvas.toDataURL();\n",
  1498. " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
  1499. "}\n",
  1500. "\n",
  1501. "mpl.figure.prototype.updated_canvas_event = function() {\n",
  1502. " // Tell IPython that the notebook contents must change.\n",
  1503. " IPython.notebook.set_dirty(true);\n",
  1504. " this.send_message(\"ack\", {});\n",
  1505. " var fig = this;\n",
  1506. " // Wait a second, then push the new image to the DOM so\n",
  1507. " // that it is saved nicely (might be nice to debounce this).\n",
  1508. " setTimeout(function () { fig.push_to_output() }, 1000);\n",
  1509. "}\n",
  1510. "\n",
  1511. "mpl.figure.prototype._init_toolbar = function() {\n",
  1512. " var fig = this;\n",
  1513. "\n",
  1514. " var nav_element = $('<div/>')\n",
  1515. " nav_element.attr('style', 'width: 100%');\n",
  1516. " this.root.append(nav_element);\n",
  1517. "\n",
  1518. " // Define a callback function for later on.\n",
  1519. " function toolbar_event(event) {\n",
  1520. " return fig.toolbar_button_onclick(event['data']);\n",
  1521. " }\n",
  1522. " function toolbar_mouse_event(event) {\n",
  1523. " return fig.toolbar_button_onmouseover(event['data']);\n",
  1524. " }\n",
  1525. "\n",
  1526. " for(var toolbar_ind in mpl.toolbar_items){\n",
  1527. " var name = mpl.toolbar_items[toolbar_ind][0];\n",
  1528. " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
  1529. " var image = mpl.toolbar_items[toolbar_ind][2];\n",
  1530. " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
  1531. "\n",
  1532. " if (!name) { continue; };\n",
  1533. "\n",
  1534. " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
  1535. " button.click(method_name, toolbar_event);\n",
  1536. " button.mouseover(tooltip, toolbar_mouse_event);\n",
  1537. " nav_element.append(button);\n",
  1538. " }\n",
  1539. "\n",
  1540. " // Add the status bar.\n",
  1541. " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
  1542. " nav_element.append(status_bar);\n",
  1543. " this.message = status_bar[0];\n",
  1544. "\n",
  1545. " // Add the close button to the window.\n",
  1546. " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
  1547. " var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
  1548. " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
  1549. " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
  1550. " buttongrp.append(button);\n",
  1551. " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
  1552. " titlebar.prepend(buttongrp);\n",
  1553. "}\n",
  1554. "\n",
  1555. "mpl.figure.prototype._root_extra_style = function(el){\n",
  1556. " var fig = this\n",
  1557. " el.on(\"remove\", function(){\n",
  1558. "\tfig.close_ws(fig, {});\n",
  1559. " });\n",
  1560. "}\n",
  1561. "\n",
  1562. "mpl.figure.prototype._canvas_extra_style = function(el){\n",
  1563. " // this is important to make the div 'focusable\n",
  1564. " el.attr('tabindex', 0)\n",
  1565. " // reach out to IPython and tell the keyboard manager to turn it's self\n",
  1566. " // off when our div gets focus\n",
  1567. "\n",
  1568. " // location in version 3\n",
  1569. " if (IPython.notebook.keyboard_manager) {\n",
  1570. " IPython.notebook.keyboard_manager.register_events(el);\n",
  1571. " }\n",
  1572. " else {\n",
  1573. " // location in version 2\n",
  1574. " IPython.keyboard_manager.register_events(el);\n",
  1575. " }\n",
  1576. "\n",
  1577. "}\n",
  1578. "\n",
  1579. "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
  1580. " var manager = IPython.notebook.keyboard_manager;\n",
  1581. " if (!manager)\n",
  1582. " manager = IPython.keyboard_manager;\n",
  1583. "\n",
  1584. " // Check for shift+enter\n",
  1585. " if (event.shiftKey && event.which == 13) {\n",
  1586. " this.canvas_div.blur();\n",
  1587. " event.shiftKey = false;\n",
  1588. " // Send a \"J\" for go to next cell\n",
  1589. " event.which = 74;\n",
  1590. " event.keyCode = 74;\n",
  1591. " manager.command_mode();\n",
  1592. " manager.handle_keydown(event);\n",
  1593. " }\n",
  1594. "}\n",
  1595. "\n",
  1596. "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
  1597. " fig.ondownload(fig, null);\n",
  1598. "}\n",
  1599. "\n",
  1600. "\n",
  1601. "mpl.find_output_cell = function(html_output) {\n",
  1602. " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
  1603. " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
  1604. " // IPython event is triggered only after the cells have been serialised, which for\n",
  1605. " // our purposes (turning an active figure into a static one), is too late.\n",
  1606. " var cells = IPython.notebook.get_cells();\n",
  1607. " var ncells = cells.length;\n",
  1608. " for (var i=0; i<ncells; i++) {\n",
  1609. " var cell = cells[i];\n",
  1610. " if (cell.cell_type === 'code'){\n",
  1611. " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
  1612. " var data = cell.output_area.outputs[j];\n",
  1613. " if (data.data) {\n",
  1614. " // IPython >= 3 moved mimebundle to data attribute of output\n",
  1615. " data = data.data;\n",
  1616. " }\n",
  1617. " if (data['text/html'] == html_output) {\n",
  1618. " return [cell, data, j];\n",
  1619. " }\n",
  1620. " }\n",
  1621. " }\n",
  1622. " }\n",
  1623. "}\n",
  1624. "\n",
  1625. "// Register the function which deals with the matplotlib target/channel.\n",
  1626. "// The kernel may be null if the page has been refreshed.\n",
  1627. "if (IPython.notebook.kernel != null) {\n",
  1628. " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
  1629. "}\n"
  1630. ],
  1631. "text/plain": [
  1632. "<IPython.core.display.Javascript object>"
  1633. ]
  1634. },
  1635. "metadata": {},
  1636. "output_type": "display_data"
  1637. },
  1638. {
  1639. "data": {
  1640. "text/html": [
  1641. "<img src=\"data:image/png;base64,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\" width=\"639.85\">"
  1642. ],
  1643. "text/plain": [
  1644. "<IPython.core.display.HTML object>"
  1645. ]
  1646. },
  1647. "metadata": {},
  1648. "output_type": "display_data"
  1649. }
  1650. ],
  1651. "source": [
  1652. "plot_traces(result)"
  1653. ]
  1654. },
  1655. {
  1656. "cell_type": "markdown",
  1657. "metadata": {},
  1658. "source": [
  1659. "Alternatively we can plot using snuffler, which will open in a seperate window."
  1660. ]
  1661. },
  1662. {
  1663. "cell_type": "code",
  1664. "execution_count": 21,
  1665. "metadata": {},
  1666. "outputs": [
  1667. {
  1668. "name": "stderr",
  1669. "output_type": "stream",
  1670. "text": [
  1671. "Traceback (most recent call last):\n",
  1672. " File \"/usr/local/lib/python3.5/dist-packages/pyrocko/gui/snuffling.py\", line 1695, in load_if_needed\n",
  1673. " self._module = __import__(self._name)\n",
  1674. " File \"/home/asteinbe/.snufflings/audio.py\", line 16, in <module>\n",
  1675. " from PyQt4.phonon import Phonon\n",
  1676. "RuntimeError: the PyQt4.QtCore and PyQt5.QtCore modules both wrap the QObject class\n",
  1677. "\n",
  1678. "Snuffling module \"/home/asteinbe/.snufflings/audio.py\" is broken\n",
  1679. "cc.py:pyrocko.gui.snuffling - ERROR - Traceback (most recent call last):\n",
  1680. " File \"/usr/local/lib/python3.5/dist-packages/pyrocko/gui/snuffling.py\", line 1695, in load_if_needed\n",
  1681. " self._module = __import__(self._name)\n",
  1682. " File \"/home/asteinbe/.snufflings/okada/snuffling.py\", line 102\n",
  1683. " print numpy.shape(disp)\n",
  1684. " ^\n",
  1685. "TabError: inconsistent use of tabs and spaces in indentation\n",
  1686. "\n",
  1687. "cc.py:pyrocko.gui.pile_viewer - WARNING - Snuffling module \"/home/asteinbe/.snufflings/okada/snuffling.py\" is broken\n"
  1688. ]
  1689. }
  1690. ],
  1691. "source": [
  1692. "plot_snuffler(result, best_source)"
  1693. ]
  1694. },
  1695. {
  1696. "cell_type": "code",
  1697. "execution_count": null,
  1698. "metadata": {},
  1699. "outputs": [],
  1700. "source": []
  1701. }
  1702. ],
  1703. "metadata": {
  1704. "kernelspec": {
  1705. "display_name": "Python 3",
  1706. "language": "python",
  1707. "name": "python3"
  1708. },
  1709. "language_info": {
  1710. "codemirror_mode": {
  1711. "name": "ipython",
  1712. "version": 3
  1713. },
  1714. "file_extension": ".py",
  1715. "mimetype": "text/x-python",
  1716. "name": "python",
  1717. "nbconvert_exporter": "python",
  1718. "pygments_lexer": "ipython3",
  1719. "version": "3.5.2"
  1720. }
  1721. },
  1722. "nbformat": 4,
  1723. "nbformat_minor": 2
  1724. }