summaryrefslogtreecommitdiff
path: root/doc/Run_analysis.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'doc/Run_analysis.ipynb')
-rw-r--r--doc/Run_analysis.ipynb5139
1 files changed, 5139 insertions, 0 deletions
diff --git a/doc/Run_analysis.ipynb b/doc/Run_analysis.ipynb
new file mode 100644
index 0000000..aeebf6d
--- /dev/null
+++ b/doc/Run_analysis.ipynb
@@ -0,0 +1,5139 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "from matplotlib import pyplot as plt\n",
+ "%matplotlib notebook\n",
+ "import numpy as np\n",
+ "import numpy.polynomial.polynomial as poly\n",
+ "\n",
+ "import statistics\n",
+ "import warnings\n",
+ "import itertools\n",
+ "import sqlite3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "db = sqlite3.connect('results.sqlite3')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def fetch_run(names_or_ids):\n",
+ " run_info, grouped, cals = [], {}, {}\n",
+ " for name_or_id in names_or_ids:\n",
+ " if type(name_or_id) is str:\n",
+ " runs = db.execute('SELECT run_id FROM runs WHERE name LIKE ?', (name_or_id,)).fetchall()\n",
+ " if len(runs) > 1:\n",
+ " raise ValueError('Ambiguous run name {} matches run ids {}'.format(run_name, runs))\n",
+ "\n",
+ " ((run_id,),), run_name = runs, name_or_id\n",
+ " else:\n",
+ " run_id, (run_name,) = name_or_id, db.execute('SELECT name FROM runs WHERE run_id == ?', (name_or_id,)).fetchone()\n",
+ " run_info.append((run_id, run_name))\n",
+ " \n",
+ " data = db.execute('''\n",
+ " SELECT channel, duty_cycle, voltage, voltage_stdev FROM measurements\n",
+ " WHERE run_id == ?\n",
+ " ORDER BY channel ASC, duty_cycle ASC;\n",
+ " ''', (run_id,)).fetchall()\n",
+ " _ch, cal_duty, *cal = data[0]\n",
+ " assert cal_duty == 0\n",
+ " cals[run_id] = cal\n",
+ " for ch, data in itertools.groupby(data, lambda elem: elem[0]):\n",
+ " if ch == -1: # skip cal data\n",
+ " continue\n",
+ " if ch in grouped:\n",
+ " warnings.warn('Duplicate data: Channel {} found in more than one run!'.format(ch))\n",
+ " grouped[ch] = [(duty, volt, stdev) for _ch, duty, volt, stdev in data]\n",
+ " return run_info, grouped, next(iter(cals.values())) # for now just use some random cal value"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def apply_style(ax):\n",
+ " ax.spines['top'].set_visible(False)\n",
+ " ax.spines['right'].set_visible(False)\n",
+ " ax.spines['bottom'].set_color('#08bdf9')\n",
+ " ax.spines['left'].set_color('#08bdf9')\n",
+ " ax.tick_params(axis='x', colors='#01769D', which='both')\n",
+ " ax.tick_params(axis='y', colors='#01769D', which='both')\n",
+ " ax.xaxis.label.set_color('#01769D')\n",
+ " ax.yaxis.label.set_color('#01769D')\n",
+ " ax.grid(color='#08bdf9', linestyle=':')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "color_bright, color_dark = '#ffd2e9', '#fe3ea0'\n",
+ "\n",
+ "def plot_run(figtitle, *names_or_ids, figsize=None, combine_plots=False, svgfile=None):\n",
+ " run_info, data, cal = fetch_run(names_or_ids)\n",
+ " \n",
+ " if combine_plots:\n",
+ " rows, cols = 1, 1\n",
+ " else:\n",
+ " rows = (len(data)+1)//2\n",
+ " cols = 2 if len(data) > 1 else 1\n",
+ " fig, axs = plt.subplots(rows, cols, figsize=figsize or (8,3*max(2, rows)), squeeze=False)\n",
+ " if figtitle:\n",
+ " fig.suptitle(figtitle)\n",
+ " if combine_plots:\n",
+ " axs = np.array([axs[0,0]] * len(names_or_ids))\n",
+ "\n",
+ " cal_volt, cal_stdev = cal\n",
+ " offsets = []\n",
+ " for ch, ax in zip(data, axs.flat):\n",
+ " ch_data = data[ch]\n",
+ " duty, volt, stdev = zip(*ch_data)\n",
+ " \n",
+ " duty = np.array(duty) / duty[0]\n",
+ " volt = np.array(volt) - cal_volt\n",
+ " vref = volt[0]\n",
+ " stdev = np.array(stdev)\n",
+ " \n",
+ " max_y = max(volt)/vref\n",
+ " min_x, max_x = min(duty), max(duty)\n",
+ " \n",
+ " offx, slope = fit_coefs = poly.polyfit(duty, volt, 1)\n",
+ " fit_func = poly.polyval(duty, fit_coefs)\n",
+ " ax.errorbar(duty, volt/vref, yerr=stdev/vref, color=color_bright, zorder=1)\n",
+ " ax.plot(duty, fit_func/vref, color=color_dark, zorder=2)\n",
+ " \n",
+ " apply_style(ax)\n",
+ " ax.set_xscale('log')\n",
+ " ax.set_yscale('log')\n",
+ " bit_offx = offx/slope\n",
+ " offsets.append(bit_offx)\n",
+ " \n",
+ " print('Channel {} offset: {:6.3f}lsb'.format(ch, bit_offx))\n",
+ " if figtitle:\n",
+ " ax.set_title('Channel {}, offset={:.3f}lsb'.format(ch, bit_offx))\n",
+ " \n",
+ " # reuse latest duty cycles here\n",
+ " ax.set_xticks(duty)\n",
+ " ax.set_xticklabels([str(i) for i in range(len(duty))])\n",
+ " ax.set_xlabel('bit index')\n",
+ " ax.set_yticks([2**i for i in range(len(duty))])\n",
+ " ax.set_yticklabels([str(2**i) for i in range(len(duty))])\n",
+ "\n",
+ " ax.set_xlim([min_x*0.9, max_x*1.1])\n",
+ " ax.set_ylim([0, max_y*1.1])\n",
+ " \n",
+ " if len(names_or_ids) > 1:\n",
+ " print('Offset statistics: mean={:.4f}lsb, stdev={:.4f}lsb'.format(\n",
+ " statistics.mean(offsets), statistics.stdev(offsets)))\n",
+ " \n",
+ " if svgfile:\n",
+ " fig.savefig(svgfile)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def fetch_runs(*names):\n",
+ " return [run_id for name in names for run_id, in db.execute('''\n",
+ " SELECT DISTINCT runs.run_id\n",
+ " FROM runs JOIN measurements USING (run_id)\n",
+ " WHERE name LIKE ? AND channel != -1\n",
+ " ''', (name,)).fetchall() ]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,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ZAPnS7uRP29u+YD5rYfDVXVf2QN09Yer8Fri6o1jruYCmK0eruYCkpktptqLXGQ9uq9n2Mrk86H/+ix04VboloPA4V6rl1m5+jPkai6A2erhai4gmdliqj2i8alq4Gxqe680tZ0y9Jix8vSTl2XwencOHX157OvP4+g7XThy3j149asPo+OmFdi15G3s2d6Fzp4BdGYVhzJ5dPSFjz39eXRmFZ1ZxeGB4vZdfcXtR0u2d5Rs78xq2fYjA8Wv7S7ZfihT3L6nP4/Xu3M4eVkGbx/LDW3f2198/v6S5+8vybqvJOuBCu9hPO9tMNfge6znvQ1uP1iyPYr31tGXR+lxtnHcKr23wf22reR4NvK4VXpvw4+njeNW6b0NP542jlul9za4394sOZ4HMnnIwkOniMikxrRh/aLq0c5jWRxoXozpLSuw7f7X0fHyXuzZdhSdRzPoHMizR9mj7FH26AnbozTBVDVw+unWSX6AocdP5+HkZRk++OCDj9gfhcHTaexRPvjgw+VHEnqUJpi6ztw1zT1Ffj5/qyw8dErZY8bK0yddPxsyY+XpI75m+xFnthtmb254rmr/zeM9b6yvj5VtPO/Z1vGMM/Pga8d9PMdz/CtlG+u16v1alMczAWfu2KMRPJLco2M953jZbHYpe5Q9SmRLXdcui4j4ZtOIbU1tp0zyA0hTm3t/aceZbbR9Ua16c1X7bx7veWN9faxs43nPUahnv8WZefC14z6etT6/9HmVso31WvV+rVYud0cV2KMRSHKPjvWc42Wz2aXsUfYokS11D5xe+uoR21z+4Y8z22j7olr15qr23zze88b6+ljZxvOeo1DPfosz8+Brx308a31+6fMqZRvrter9Wq1ncZmlAAAKhklEQVRc7o4qsEcjkOQeHes5x8tms0vZo+xRooa6avofitd+hnjtZ0zyA4hnmsVrP0Ounfln43pdl3/4Xc3mai4RZquHq7lEmC1q7FF3uJpLhNnq4WouEWYjGpdUenLZzZCFh/hm1rhet6ntveKnW6Wp7b3RBI2Qq9lczSXCbPVwNZcIs0WNPeoOV3OJMFs9XM0lwmxERERERERERERERERERERERERERERERERERERERERERO7y0leLZ7aLZ/rFN6ul2fy17UgiItJizhQvWCC+2V33XP1xSJnrxTNrxDfd4gf7xTOPiB983HYsERHx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\" width=\"800\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Channel 31 offset: 2.681lsb\n",
+ "Channel 30 offset: 2.633lsb\n",
+ "Channel 29 offset: 2.616lsb\n",
+ "Channel 28 offset: 2.643lsb\n",
+ "Offset statistics: mean=2.6432lsb, stdev=0.0276lsb\n"
+ ]
+ }
+ ],
+ "source": [
+ "plot_run('All channels, blue runs', *fetch_runs('green1', 'green2', 'green3', 'green4'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAYAAAByNR6YAAAgAElEQVR4nO3deZQc5Z3m+1d2X5uZtrnT9wwzPs1MXxu77TPd9hjOdM89d+Z2id1sZrNlEBiDdzbZSJURDYwX9YBXvNAyQqgyApdKu5CE2IQkJBCgXYAW0IL2pbSUqkq1L5mR8XvuH1FVkSWVKqMqlzcy3+dzTp3Tjq7Kiq+ipPdH1puRShEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREcXKGLW0+Xyl1BjdJ0JERERUGZY2n3/eqhTaPMFwen3BY/s99PrDf14lMrkdYD/72W9qv8ntQPR+3cs4xY2VfEDZzk71aN3uKANWmyeI8nmVyOR2gP3sZ7+p/Sa3A9H7dS/nFFcRn8Fq8wQXrDbzL5rJ7QD72c9+U/tNbgei9+teximuIg5YREREdDbdyzjFFQcsIiKiUdO9jFNcccAiIiIaNd3LOMXVCPZgmTqImdwOsJ/97De13+R2AGg73YOvPb2fe7BolDhg5WRyO8B+9rPf1H6T2+V4O7zxi+CNnYHOFQeG/VzdyzjFFQesnExuB9jPfvab2m9qu+w8BblxHqSqFsevm4eOd08M+/m6l3GKq4gDloigzROImPUXDTC7HWA/+9lvar+J7fL2YcjVsyBVtZDbFqJ9/+mc/bqXcYorbnInIiKCLNoJuXRGMFx9/yXI6e5IX6d7Gae44oBFREQGE9+HTN0cDFZVtRD7NUiPF/nrdS/jFFcRB6x2T3DRmhTaDRzETG4H2M9+9pvab0K7pDOQn78RDle/WwfJ+ACi9+teximuuMk9J5PbAfazn/2m9ld6u3SkIA8sDQarsbWQmduBrP1WfC9Cyg8HrJxMbgfYz372m9pfye1yvANy5+JguLpyJuS1/Wd9DgesSmYl71O2u11ZTruynHZlO+tV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lFUzVlU/83fKct5Strt24GsSNd9QltOrEsnvBufiPK4sp33QgBWc33FVnbxVJZKfUdXJW5XlNKtq5+6s812gLHeTunTyX6iEc72y3ZSqTv63gv65EREREZ1TMGDtVNnPWCWcX/cd6/ucwZvcI/2KcLhnsAYeN3ndGNuFumfyeX3fZ51KOFPPOL8NgwYsy9mnrOT4wZ/j/ERZzrqB/33f03+lbOeospynle2cVJb7aM4/ByIiIqKCsdzVynafHXQskbxJ2Y6nxo37aPA5BRywsp/xmuRcMsZ2oX48/W/6zqVFWclvDXoc2/3jwICVeOIv+54F6w5+Ddj/4fQqy204o+vq4DzdtUpN/siI/kyIiIiI8lLqAeuhP/678HvXXBwcm/bpvnNpUbZz16DHyR6wfpz8j31D051qovO5QR+J5GcGf53zuLLcjLLdg2rClPNH8kdCRERElJ/wV4TZx3413K8IleWkleV+bdjHHdWANcSvCG1n/eBfEbr1KpH86bDfe1LN/1CWk1bVNdcq292uLHfGsJ9PREREVFDhJvc/KNv9grKS45XldqqE88Pwc84csNw9ynKeVtbUT6n7nv6rIR93VANW8jZluz0qkfy2mlTzeWU5/3LWJvfgFYTdKpH8kZpU83k1cfqXVCL5bZVwJymllLLdTyrb3a9s5/dKKaUmTv9S36sNxxXmD4yIiIgoF8tdrRLO1OBWBm6bsp3Tykr+Qp3rNg1KKZVwvqpsZ6+yHW/Et2kYbsAKzudRZTmNynY6lO3UKsv5zVm3aUg4dyjL2aJsN6Vs57SynTdVouYWpZRStvusst3tasKUj4ef705SltOsJk67cLR/TEREREREREREREREREREREREREREdLb/H0ekbhYuc8NxAAAAAElFTkSuQmCC\" width=\"600\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Channel 31 offset: 2.681lsb\n"
+ ]
+ }
+ ],
+ "source": [
+ "plot_run(None, *fetch_runs('green1'), figsize=(6, 4), svgfile='/tmp/driver_linearity_raw.svg')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,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\" width=\"800\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def bitslide(nbits, offx_lsb):\n",
+ " return [ sum((2**n + offx_lsb) if i&(2**n) else 0 for n in range(nbits)) for i in range(2**nbits) ]\n",
+ "\n",
+ "def plot_bitslide(data):\n",
+ " fig, (axl, axr) = plt.subplots(1, 2, figsize=(8, 3))\n",
+ " apply_style(axl)\n",
+ " apply_style(axr)\n",
+ " axl.plot(data, color=color_dark)\n",
+ " axr.plot(data, color=color_dark)\n",
+ " axr.set_yscale('log')\n",
+ " axr.set_xscale('log')\n",
+ " axl.set_xlim((0, len(data)))\n",
+ " axr.set_xlim((0, len(data)))\n",
+ "\n",
+ "plot_bitslide(bitslide(8, 2.5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,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\" width=\"600\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def frob_export_for_blog(data, svgfile=None):\n",
+ " fig, ax = plt.subplots(1, 1, figsize=(6, 4))\n",
+ " apply_style(ax)\n",
+ " ax.plot(data, color=color_dark)\n",
+ " ax.set_yscale('log')\n",
+ " ax.set_xscale('log')\n",
+ " ax.set_xlim((0, len(data)))\n",
+ " if svgfile:\n",
+ " fig.savefig(svgfile)\n",
+ "\n",
+ "frob_export_for_blog(bitslide(8, 2.5), svgfile='/tmp/uncorrected_brightness_sim.svg')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nAABJRU5ErkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x72df4cb50dd8>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def cutoff_reference(nbits, offx_lsb, cutoff):\n",
+ " return [ sum((2**n + offx_lsb) if i&(2**n) else 0 for n in range(cutoff, nbits))\n",
+ " for i in range(2**nbits) ]\n",
+ "\n",
+ "plot_bitslide(cutoff_reference(8, 2.5, 3))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAF2CAYAAAB0yCWXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XeYlNXZx/Hvwd67xhZJrCgaFXtdQhTs5bXE3mLvGnvU\nVRML9hY10SCCgFgRC8Y2qFERaaIUu6goaBRUjLQ97x9nEYRlC7M7z5Tv57r22tmZZ3ZvCPHs7znn\n3CfEGJEkSZIkqVBaZV2AJEmSJKmyGEQlSZIkSQVlEJUkSZIkFZRBVJIkSZJUUAZRSZIkSVJBGUQl\nSZIkSQVlEJUkSZIkFZRBVJIkSZJUUA0G0RDCQiGEASGEISGE4SGES2ufbx1CeD2EMDqE0DOEMH/t\n8wuGEHqFEN4LIbwWQvh1S/8hJElS/UII64UQ7ggh9A4hnJB1PZKkytZgEI0xTgbaxxg3ATYGdgkh\nbAlcA1wfY1wXmAAcU/uWY4BvYoxrAzcBnVukckmS1GgxxlExxhOBA4F2WdcjSapsjVqaG2P8sfbh\nQsD8QATaAw/XPt8V2Lv28V61XwM8BHRolkolSdLPQgj3hBDGhRDemu35TiGEUSGEd0MI58322h7A\ny8DzhaxVkqTZNSqIhhBahRCGAF8CzwIfABNijDW1l3wGrFr7eFXgU4AY43RgQghh2WatWpIkdQE6\nzvpECKEVcFvt8xsAB4UQ1pvxeoyxb4xxO+DQQhYqSdLs5m/MRbWBc5MQwpLAo0Cbui6r/Rxmez7M\n8pokSWoGMcZXQghrzPb0FsB7McZPAEIIvUgrlUaFEHYE9iWtbnqyoMVKkjSbRgXRGWKM34UQ+gNb\nAUuHEFrVhtTVgLG1l30GrA6MDSHMBywZY/x29u8VQjCcSpKaVYxx9puhlebnVUm1PiOFU2KM/YH+\n9b3ZsVmS1NzmNjY3pmvu8iGEpWofLwL8ARgBvAjsX3vZEUCf2seP135N7esv1FOUH/Pwcemll2Ze\nQyl/+Pfn351/d6X30Zi/PwFzrkqCJq5Kyvp/60L+mymVn5vv95yX9zf1PY25vjmuKZf/lvrvM//3\nN+V9jb02339/5fLvszn/LPVpzIzoykDX2n0nrYAHYoxPhRBGAr1CCFcAQ4B7aq+/B+gWQngP+C/w\nx6YMgJIkaZ59Bsx6bNqsK5YqSlVVVdn83Hy/57y8v6nvacz1zXVNOfDfZ/7vb8r7GnttQ9dVyr9P\nKMyftcEgGmMcDmxax/MfAVvW8fxk4IBmqU6SJNUn8MtZ0IHAWrV7R78g3Qw+KIvCsuYv+vm93yDa\nsvz3mf/7DaItqxB/1kZ1zVVxqaT/E7QE//7mnX93886/u/z49zenEEIP4FVgnRDCmBDCUTF1qz8V\n+DfwDtArxjgyyzql5uR/C1TM/PfZNKGhtbst9oNDiFn9bElS+QkhEG1WlJcQQrz00kupqqryFypJ\n0jzL5XLkcjkuu+yyuY7NBlFJUlkwiObPsVmS1JzqG5tdmitJkiRJKiiDqCRJkiSpoAyikiRJkqSC\nMohKkqSfVVdXk8vlsi5DklTCcrkc1dXV9V5jsyJJUlmwWVH+HJslSc3JZkWSJEmSpKJhEJUkSZIk\nFZRBVJIkSZJUUAZRSZIkSVJBGUQlSZIkSQVlEJUkST/z+BZJUr48vkWSVDE8viV/js2SpObk8S2S\nJEmSpKJhEJUkSZIkFZRBVJIkSZJUUAZRSZIkSVJBGUQlSZIkSQVlEJUkST/z+BZJUr48vkWSVDE8\nviV/js2SpObk8S2SpLI1fXrWFUiSpKYyiEqSStbYsbD++oZRSZJKjUFUklSy/vUvqKqC+ebLuhJJ\nktQU7hGVJJWk6dPhN7+BPn1gk03cI9ocHJslSc3JPaKSpLLz9NOw8sophEqSpNJiEJUklZw334Qz\nzoDTTsu6EkmSNC8MopKkktKvH+y6K/ztb3DIIVlXI0mS5sX8WRcgSVJjjR8PRx8NDz4IO+6YdTXl\nqbq6mqqqKqqqqrIuRZJUonK5HLlcrt5rbFYkSSoJU6fCHnvAppvClVfO+brNivLn2CxJak71jc0G\nUUlS0aupgcMOgwkT4LHHYIEF5rzGIJo/x2ZJUnOqb2x2aa4kqehdcgl89lnaH1pXCJUkSaXFICpJ\nKmovvQT/+hcMGQKLLJJ1NZIkqTnYNVeSVJTGjoUbb4SDDoK774aVVsq6IkmS1FwMopKkovLVV7DT\nTtC2LQwfDj16pONaJElS+XBpriSpqFx/PayyCvTtCwsvnHU1kiSpJdg1V5JUNCZMgDXXhEGDoHXr\npr3Xrrn5c2yWJDWn+sZml+ZKkopCTQ1ce21ahtvUECpJkkqLS3MlSZl6+23o2hV69YJll4WHHsq6\nIkmS1NKcEZUkZWbIEKiqggUXhKefhmHDYO21s66qslVXV5PL5bIuQ5JUwnK5HNXV1fVe4x5RSVIm\nfvwR2rWDSy5JR7Tkyz2i+XNsliQ1p/rGZoOoJKngamrg0EOhVSvo3r15vqdBNH+OzZKk5lTf2Owe\nUUlSwXz8MYweDb17w9ixaTmuJEmqPAZRSVJBjB8P22wDG2wAK6+czgldZJGsq5IkSVlwaa4kqcXF\nCHvuCW3bwlVXtczPcGlu/hybJUnNyT2ikqTMTJgAJ58M778PL7+cOuS2BINo/hybJUnNqb6xucHj\nW0IIq4UQXgghjAghDA8hnFr7/KUhhM9CCINrPzrN8p4LQgjvhRBGhhB2br4/iiSpVHz4IZx1Fqy3\nHiy9NLz4YsuFUEmSVFoas0d0GnBWjHFoCGFxYFAI4dna126IMd4w68UhhDbAAUAbYDXguRDC2t5i\nlaTKce+9cM45cNxx0L8/rLtu1hVJkqRi0mAQjTF+CXxZ+/iHEMJIYNXal+uaZt0L6BVjnAZ8HEJ4\nD9gCGNA8JUuSitmjj8Jll6UZ0LZts65GkiQVowaX5s4qhNAa2JiZofLkEMLQEMLdIYSlap9bFfh0\nlrd9zszgKkkqU1OnwpgxcOKJ0KOHIVSSJM1do49vqV2W+xBweu3M6N+By2OMMYTwV+B64E/UPUta\n57Lc6urqnx9XVVVRVVXV+MolSUXjrrvg1FPT48svh623bvmfmcvlyOVyLf+DJElSs2tU19wQwvzA\nE8DTMcab63h9DaBvjHGjEML5QIwxXlP7Wj/g0hjjgNne47ZRSSoD998P552X9oKuuWZ2ddg1N3+O\nzZKk5pRX19xa/wJGzBpCQwi/muX1fYG3ax8/DvwxhLBgCOE3wFrAG00vW5JU7N5+G04/Hfr1yzaE\nSpKk0tLg0twQwrbAIcDwEMIQ0jLbC4GDQwgbAzXAx8DxADHGESGE3sAIYCpwkrdXJan8/PQTHHww\ndO7sftByUl1d7XYZSVJeGrN9plFLc1uCy38kqfTECK+/npoR9e4Nu+wCXbpAKIIFsS7NzZ9jsySp\nOdU3Nje6WZEkSWeeCU8+CYcfDv/5D6y1VtYVSZKkUmQQlSQ1ypdfQteuMHo0rLhi1tVIkqRiNmhQ\n/a836RxRSVLluvFGOOQQQ6gkSarfRx9Bp071X2MQlSTVa+JEuPdeuPtu+POfs65GkiQVs8GDoWNH\nuPDC+q8ziEqS6jRmDOy3H/z619CnD3TvDq1bZ12VJEkqVt26wU47wVlnpb4S9XGPqCRVoFwOttoK\nFl647tenTYODDoLttoN//hOWWaag5UmSpBIyfjycfXZqZNi3L2yzTcPvcUZUkirMxImw++7Qv//c\nr7nySlh0UbjqKkOoJEmau3790nniK60Ew4c3LoSCM6KSVHHuvx8mTYJRo9Iejtl17w7/+AcMGACt\nvF0pSZLqEGPaB3r33eljr72a9n6DqCRVkBjhzjthn31g5Mg5X3/qKTjnHHj+eVh11cLXJ0mSittV\nV0G7dnDNNfDVVzBiBKywQtO/j/e6JamC9OsHkyfDSSelGdFZjR0LRx8NDz0E66+fTX2SJKl49e2b\nZkE7doRll4WhQ+cthIJBVJIqQozwt7/BkUfCrbdCmza/nBGdPBmOOAJOPBG23TazMiVJUpG68UY4\n5hg4//z09f3357eFJ8QYm6eypv7gEGJWP1uSKk23bmkpzbPPpiW3McJSS8HHH6dOdwceCGuvDb16\nwfwlumkjhECMMWRdRylzbJYkze6nn+CEE1JH3AcfhI03hunTYb75Gn5vfWOzM6KSVOY+/DCd59Wz\n58x9nyHAeuvB6NFplvTww9PgUqohVJIkNb+XX4ZNN03Hur32Wgqh0LgQ2hBnRCWpjH39NVRVwXHH\nwWmn/fK1ww+HpZeGxx6Djz5qnkElS86I5s+xWZIEaRb0vPPg4Yfh5pth333TTeymqm9s9t63JJWp\nSZOgU6d0Zuipp875eps2cMkl6aPUQ6gkSWoeb70FZ56ZtvG8/jqstlrL/ByX5kpSmTrzzLT89qqr\n6r6Lud56aZA55pjC1yZJkorD5MnQti38+GPqirvHHmk1Vb9+LRdCwRlRSSo7Mab9oM8/D0OGzH0p\nzfbbwy23wCqrFLY+SZJUHKZPh6OOgnfegdtvh+uvT+eN77XXvC3FbQr3iEpSmfjoo9Qdt0cPmDo1\nhdEttsi6qsJxj2j+HJslqXJ88QX85S+pqeHIkTBuXGpOtN12zfcz7JorSWXum29g883hv/+Frl3h\n/fcrK4Sq+VRXV5PL5bIuQ5LUgoYPh/btoaYGHn0UDjoonQ/aXCE0l8tRXV1d7zXOiEpSGbj88nQm\n6L/+lXUl2XFGNH+OzZJU3mKE7t3TsW5nnAEXXtiyS3DtmitJZWzSJLjttrScRpIkqS7vvQcnnphW\nTz39NGy2Wbb1uDRXkkrUlCnwxBOw//6www6w7rpZVyRJkorR3XfDllvCLrvAwIHZh1BwRlSSStKN\nN8Lf/paOYDn4YDjkkKwrkiRJxWbcOLj00jQD+sgj6ViWYmEQlaQS88ILcN116ZDptdbKuhpJklRM\namqgVSsYNiydKb7qqvCf/7TsmaDzwqW5klRCvv4ajjwyNSUyhEqSpFmddRZsvDG8/TbstBN06AB3\n3VV8IRTsmitJJeO77+D3v4dOneCvf826muJj19z8OTZLUul66inYbbf0eLXV4Jpr0vadLHmOqCSV\nsEcfha23ho02So0Grrgi64okSVIxefVVOOII6N8/fX3qqdmH0IY4IypJReyjj2CLLeCf/0x3Nzfd\nNO370JycEc2fY7MklZ5jjkld9O++G/bYA/r2hY4dYcEFs66s/rHZICpJRerbb9MSm//7Pzj77Kyr\nKX4G0fw5NktS6fj44zQL+umnaU/oootmXdGcXJorSSVk8mR46KHUbGCzzVLHO0mSpBl69YLtt4dd\nd4URI4ozhDbE41skqUjEmJbVnH8+bLhh6nLXqVPWVUmSpGLx2WepYWGfPvD3v8M++2Rd0bwziEpS\nEYgxHcvy1lup0UDbtllXJEmSiskDD6StOgcfDEOGwK9+lXVF+TGISlIRuPvuFEJfew0WXjjraiRJ\nUhZqauZsSvjdd+n88Ouug+uvhwMPzKa25mYQlaSMTJ8Ot94KX34J99wDL71kCJUkqVJNnZo63Q4e\nDJtskp6bPBnatYO11oJnn4U2bbKtsTnZrEiSMhAjnHgiPPggLLlkWm5TToOLJElqvGnT4IQT0uMP\nP0yf+/ZNvxv87nfw9NPl93uCx7dIUgYuvxyefBKeew6WWCLrasqDx7fkz7FZkgpv+nQ49lgYMwZW\nXTV1zd9uu9QRt3dvqKqCUKKjm8e3SFIR+c9/4I47Usc7Q6gkSZVr4EA49NA0C/roo7DRRtCtG+y5\nZ9oX2r596YbQhhhEJalA/vc/ePhhOOQQ+Mc/Sr/bnSRJmndvvw277AJrrw2PPZZuTq+ySuqIe+ed\nsMceWVfYsmxWJEkt7Ouv4Zxz0iDTrh1cfXX5Dy6SJKluU6fCUUellVE33JCW5c7Qti2svz7stVd2\n9RWKQVSSWthVV6XZ0HfeSXc6JUlSZXrpJbjxRpgyBcaOnXOLzoYbpt8XKoFLcyWpBf33v9ClC1x7\nrSFUkqRK9dNPcN99sN9+qQvuww/bJ8IZUUlqpEceSYPGTjs1/j233gp77w2rr95ydUmSpOI1YEAK\noGuuCU89BZttlnVFxcEgKkmNECOcfz506tRwEB0/Pp0L2qNH6oL3yiuFqVGSJBWPSZPg6KOhXz/o\n2jXdmNZMLs2VpEZ48UX44AP4+OP6rxs2DNZbD954Ay65BD77LHXDkyRJlWP0aDjgAFhggfTYEDqn\nkNXB1R6aLamUHHAALLlkOu9r2LC6r/nf/9Jym/PPh8MOK2x9qv/QbDWOY7Mk5e+qq+CWW+DAA6Fz\nZ1hwwawryk59Y7NLcyWpAU8+Cc89B4MHpwYDdYkRTjopdbs79NDC1idJkrL36aepIdENN8CgQdC6\nddYVFTeX5kpSPS66CE4+OZ31tcYaKXBOmPDLa2KEs8+GkSPhn/+E4JycilAIYa8Qwj9CCI+GEJrQ\nckuSNLuvv4aDDkq/AwCMGwc77pi25Dz5pCG0MRoMoiGE1UIIL4QQRoQQhocQTqt9fpkQwr9DCKND\nCM+EEJaa5T23hBDeCyEMDSFs3JJ/AElqKY8/nhoODR4M22+fAuYaa8y5T/See+Df/06d8Cq9FbuK\nV4yxT4zxOOAo4ICs65GkUnbttdCrV5oFHT8+/Z5w9NFwxx2w1VZZV1caGjMjOg04K8a4PrA1cHII\nYT3gfOC5GOO6wAvABQAhhF2ANWOMawPHA3e2SOWS1ILGjoXjj4du3WDZZWc+37r1L4Pou++mPaEP\nPPDL66SWFkK4J4QwLoTw1mzPdwohjAohvBtCOK+Ot/4FuL0wVUpSeYkRTj0VeveeeR7oLruk41n+\n8pesqystDQbRGOOXMcahtY9/AEYCqwF7AV1rL+ta+zW1n++rvX4AsFQIYaVmrluSWszXX8POO8MZ\nZ8B22/3ytdat4ZNP0uPhw2GvveCyy2CDDQpeptQF6DjrEyGEVsBttc9vABxUe/N4xutXA0/NGNcl\nSY034yi3V16Bt95KR7qddVb6XeCvf826utLTpD2iIYTWwMbA68BKMcZxkMIqsGLtZasCn87yts9r\nn5OkojdlCuy2G+y+O5x77pyvz1ia++KL8Pvfp2tOOqngZUrEGF8Bvp3t6S2A92KMn8QYpwK9qL1R\nHEI4FegA7BdCOK6gxUpSiZs6NfWNePFFePbZtBVnk01g9dXhgguglZ13mqzRXXNDCIsDDwGnxxh/\nCCHMrb97XW066ry2urr658dVVVVUVVU1thxJahEXXwy/+lVqvV5X06HWreHVV9PekGuvhSOPLHSF\nmiGXy5HL5bIuo9jMfjP4M1I4JcZ4K3BrQ9/AsVmSfunqq9MxLG3awBNPwPLLp+f32w+23TadFaqk\nKWNzo84RDSHMDzwBPB1jvLn2uZFAVYxxXAjhV8CLMcY2IYQ7ax8/UHvdKGDHGbOns3xPzyqTVDS+\n/Ra6d0+DzdChsMIKdV83cGBagjNlSmpQsMgiha1Tc1eJ54iGENYA+sYYN6r9ej9g59qmRIQQDgU2\njzGe3sjv59gsSbMYPBg6dkzjv51wm66+sbmxk8j/AkbMCKG1HgeOrH18JNBnlucPr/3BWwETZg+h\nklQsBgyAffZJg0v//umYlrmFUEjXffEFHHaYIVRF6TPg17N8vRowNqNaJKlkDR+emhF17AjXXWcI\nbQkNzoiGELYFXgKGk5bYRuBC4A2gN7A6MAbYP8Y4ofY9twGdgEnAUTHGwXV8X++6SsrUtGmwzjpw\n+ulpie1SSzX4FmKEFVeEl1+G9dZr+HoVToXOiLYmzYhuWPv1fMBo0l7QL0hj9UExxpGN/H6OzZIq\n3kcfQfv2abvOkUfCfPNlXVHpqm9sbtTS3JbgYCcpa/ffD3fdBS+91LT3/fgjLLpoy9SkeVdpQTSE\n0AOoApYDxgGXxhi71B6jdhNp1dM9Mcarm/A9HZslVaxvv01HsQwfnvaEnnxy1hWVvvrG5kY3K5Kk\nclJTM7P5QFMZQlUMYowHz+X5p4Gn5/X7VldX26RIUkWpqUmNCM86C7baCp55pnGrpDR3jWla5Iyo\npIrywQfQsyf06JH2guZydXfHVemptBnRluDYLKnSDB4Mhx+ewuhpp8Gxx7oUtzk1R7MiSSp5110H\nW28N48bBPfcYQiVJqlTjx0O3bunc8PPPh3fegRNOMIQWkjOikirCm2/Crrumz7/+dcPXq/Q4I5o/\nx2ZJleCDD+APf4ANN4T990+d8NUy3CMqqaJ9/TUcfDDceqshVJKkSvb++2kW9M9/thlR1lyaK6ls\n/fADfP45dOoE++4LBx6YdUWSJCkLAwbA+uvDdtulPaGG0OwZRCWVpSeeSOd9tm0LO+wAV12VdUVS\naaiurm6w06EkFZMffqj/9ZoaOOkkOOMMGDsWLrywMHVVslwuR3V1db3XuEdUUtkZNw423hh694bt\nt8+6GhWKe0Tz59gsqdQ8+ywccUQKmLObOBF69YKHH4bvv09HtNiksLDcIyqpYnz6aVqCe/TRhlBJ\nkspZjHDBBfDFF/Df/8Jyy8187aef0tacFVZIvxPstpshtNi4NFdSWXj/faiuhnbtUhOCyy/PuiJJ\nktRSvvgCDjkkhct27eDdd2e+9r//pZvSq68Ojz0Gf/wjLLFEdrWqbgZRSSVt2jS44grYZpu0BOeF\nF9LeD88BkySpPH39NbRvD6uumsb99dabGUSnT4f/+z9YdFHo3h1amXaKlktzJZW044+HDz+EIUPS\ngCRJksrXp5/CHnvAPvvMbES4zjowejRMmgSnnw5TpkC3bjC/SaeoeY9AUsl66CF46SXo29cQKklS\nufv447QC6tBD4corZz6/7rowalTqDfHjj/Dgg4bQUuD/RJJKyvTp6W7nK6/AJ5/AM8/A4otnXZVU\nPqqrq6mqqqKqqirrUiQJSFtvnn8+bb0591w49dRfvr7OOvDkk+nItvvvtylRMcjlcg0eBebxLZJK\nRoxpKe7778P118Oyy8Iaa2RdlYqFx7fkz7FZUrH505/ggQfSTOgf/whHHTXnNT/8kJoR9eyZrlHx\n8PgWSWXh5pvTXtAXXrD7nSRJ5e6JJ+Dll+HLL2GxxeZ+3eKLp5nQ/fYrXG3KnzOikkrCW29Bhw4w\nYAD89rdZV6Ni5Ixo/hybJRWDr7+GZ59NS3Hvugt23jnrijSv6hubbVYkqai98w5cdBF07JiW4xpC\nJUkqTz/9BHvvDWuuCb16wWWXGULLmUtzJRWl//0vnRH22Wdw0EHw1FOwySZZVyVJklrC9OlwxBGw\n4IIwfjwstFDWFamlGUQlFaUuXWC55eDVVz2MWpKkcvXjj/Ddd3DccekmdN++htBK4a93korOtGlw\n7bVpSa4hVCqs6urqBlvuS1JzePZZWHFFWG89WGWVtPpp4YWzrkrNIZfLUV1dXe81NiuSVFR++glu\nugmefhr698+6GpUSmxXlz7FZUqH85z+wzz7wyCOw3XZZV6OWYrMiSUXvzTfh6KPTHdFnn01HtUiS\npPLx449p6e3BB8P++6dtOIbQymUQldSiampg3Lj6r/ngA9hlF9hgA3j7bXj+edh448LUJ0mSWlaM\ncPfdsNZacMMN0K4djB4Nu+2WdWXKkktzJbWorl3hjjvg9dfrfn3qVNh++9QZ9/TTC1ubyotLc/Pn\n2CypJVx0ETz5ZAqjm22WdTUqpPrGZoOopBa11VYwYgRMnAhhtv8MxQjHH5+OaHniCRsTKT8G0fw5\nNktqLu+9B336wJgx8MwzaU/o8stnXZUKzT2ikjIxZAiMHZs64I0dO+fr554Lb70FDzxgCJUkqVz0\n6wfbbgsffgiLLJKCqCFUs/McUUkt5o474Nhj057PUaNg1VVnvvbww/Doo/DGG7DEEtnVKEmSms/j\nj6ex/+GH09YbaW4MopKa3aRJcNZZqfvta6/B55/DyJHQoUN6/fPP4aST0mC17LLZ1ipJkprHK6/A\nMcek80A33zzralTsDKKSmlWMcOSR6fGwYbDkktCmTZoRBcjl4Igj4JxzYMsts6pS0txUV1dTVVVF\nVVVV1qVIKnLTp6dVT888kz6+/BK6dzeECnK5HLlcrt5rbFYkqVl16QI33piW3C68cHrumWegc2f4\n+9/TnpFu3dJxLVJzsllR/hybJTXFBRekc0EPPBB23jl1xJ1vvqyrUjGxa66kghg4EHbdFV58Edq2\nnfn8mDGw9dZpoFp4YbjyyuxqVPkyiObPsVlSY40enW4uDx8OK6+cdTUqVgZRSS3u7bfhD3+Af/4T\n9tjjl6/V1KSGRAstBIMGwW9+k02NKm8G0fw5NktqjBihY0fo1Cn1hJDmpr6x2T2ikvL2/few995w\n3XVzhlBIR7Osuy6stJIhVJKkUvTDD2nFU79+acvNssvCqadmXZVKmUFUUt5OPx123BEOPXTu1+y7\nL2yzTeFqkiRJzaN//3TDeZNN0izoI4/AhhtCcA2K8uDSXEnzZOxYeOAB6NEDfvwRBgyAxRfPuipV\nMpfm5s+xWSp/48en7vZ9+sACCzR8/Vtvpa03vXrB73/f4uWpzNQ3NrcqdDGSSl/v3rDBBmlwuvLK\ndEyLIVSSpOJ34YXw9NPwzjsNX/v226kJ4a23GkLV/FyaK6lJamqguhoefDDdIZUkSaVh4EB46inY\na6/0eOON537tU0+lmdObbkpd76Xm5oyopCbp0yfNfnbokHUlkiSpsWpq4JRT0kqmDh1SEJ2bxx6D\nY45Jnw8+uHA1qrIYRCU1Sk0NvPQSXHxxOsDaBgWSJJWGTz+FP/0pjd2HHw6bbz73IPr663DssdC3\nr00G1bIMopLqNXlyCp5rrJHupB51VFrSI6k8VVdXk8vlsi5DUjOYOjV1tv/d72CFFeCJJ9KRahtv\nDKNHw//+98vrX34Z9tkHunSBzTbLpmaVh1wuR3V1db3X2DVXUr3+/GcYPhyuvx7ats26Gmnu7Jqb\nP8dmqXxMnQoHHZTCZteusPzyv3x9003h9tth661h3LgUWF99FW65JR3VIjWH+sZmmxVJmqvnnkvt\n2ocNg+Xre/y0AAAgAElEQVSWy7oaSZLUGFOnwh//CFOmpDM/F1pozms23xzefDMF0bPOgiWXhFGj\nYNFFC1+vKpNBVFKdhg+HQw6Bnj0NoZIklYovv0wNhpZYAh56qO4QCimIvvQSvP8+/Pvf8MEHhlAV\nlntEJf0sRrj5ZjjjDOjUKS3P8dwwSZJKw/PPpyW3O+ww95nQGWY0LLr6ajjppDQjKhWSe0Ql/axr\nV+jcOXXL22AD2GmnrCuSGs89ovlzbJZKV7ducO656XNjzvmeNg2WXjqF1XffdfWTWoZ7RCU16N13\nU2OiF16ADTfMuhpJktRYPXrAeeelGdH112/ce+afP3XT3WYbQ6iy0eDS3BDCPSGEcSGEt2Z57tIQ\nwmchhMG1H51mee2CEMJ7IYSRIYSdW6pwSc1j+nTo3h222y7NhhpCJUkqDdOmpRnQs89O+zwbG0Jn\nuO8+aOCEDanFNGZGtAtwK3DfbM/fEGO8YdYnQghtgAOANsBqwHMhhLVd5yMVn2nTUvC87TZYdVXo\n1y/tK5EkScVp2jQYOhRefBFyOXjlFWjdOo3h83LE2pprNneFUuM1GERjjK+EENao46W61vruBfSK\nMU4DPg4hvAdsAQzIr0xJzemrr2DPPVNHveeea/odVEmSVDgxpiNWunSB1VaDqio4+mi4915YYYWs\nq5PmTT57RE8OIRwGvAmcHWOcCKwKvDbLNZ/XPiepSMSYBq8ttoAbb4RW9s6WJKmoPfggPPMMjB4N\nK62UdTVS85jXIPp34PIYYwwh/BW4HvgTdc+SznVZbvUsi9Krqqqoqqqax3IkNWTixLSMZ+BAGDsW\nHn7YEKrSlsvlyOVyWZchSS1q/Hg47TTo08cQqvLSqONbapfm9o0xblTfayGE84EYY7ym9rV+wKUx\nxjmW5toiXiqciROhQwdYbLG0hOfKK2GddbKuSmpeHt+SP8dmqfgccEDaB9q5c9aVSE3XHMe3BGaZ\n7Qwh/CrG+GXtl/sCb9c+fhy4P4RwI2lJ7lrAG/NUtaRmMXUq7LEHbLUV3HorBH9NlySpJDz4ILz1\nVjrnWyo3DQbREEIPoApYLoQwBrgUaB9C2BioAT4GjgeIMY4IIfQGRgBTgZO8tSplq7o6NSW65RZD\nqKSGVVdXu11Gysj336dOuLlc6ow7enTqiLvIIllXJjVNY7bPNGppbktw+Y/UsqZNS/tAzzwThgxx\nX4nKn0tz8+fYLBXe6NGpG+6LL8I778Bmm0H79qkz7pZbwsILZ12hNO+aY2mupAIbPRrWXbfp7xs5\nEu64A3r3hl//Gnr2NIRKklSMhgyBXXaBo46Ca65JwdPZT1UKg6hUhN5/P53t+e23sOSSjX/flCnQ\nqRMcdhi8/DKsvXbL1ShJkubdoEGw667p5vG++2ZdjVR4BlGpCP3jH1BTA1980bQg2qNHCp9//WvL\n1SZJkvIzcCDsvjvcdRfsvXfW1UjZ8BRBqchMngz33ptatY8d2/j31dSkZT0XXthSlUmSpHz17Qu7\n7QZ3320IVWVzRlQqMj17wu9+Byuu2Lgg+t138NhjcN99sOyyqcGBJEkqLlOnppvFDzyQxu1ttsm6\nIilbzohKRaKmJi2pPffcdOTKKqs0HETvuANWXz11xz3uOHj2WY9okSQpa9Omwf/+N/Pjww9hxx1h\nxIjUoMgQKjkjKhWNG29Md0gHD4bVVoM33oAxY+Z+/ZAhcMkl6fo11yxcnZIkae5GjYKdd4avvpr5\n3Pzzw8UXw5//DK2cBpIAg6hUFIYOTfs733gjhVBIM6Kvv1739RMnwsEHw003GUIlSSoWw4dDx45w\n1VVwxBFZVyMVN4OolLEvvoD99kszoq1bz3x+bktzJ01KTQ7+8Ac45JCClSlJkuoxaFAan2++GQ48\nMOtqpOJnEJUy9M03sNNO6SDr2UNlXUE0Rjj00DQLevPNhatTkiTN3WuvwV57peNY9tkn62qk0mAQ\nlTISIxx9NHToUPeRKyuvnIJojDMbEP3jH/DJJ2nAc4+JJEnZGjsWrrsOunaFbt1g112zrkgqHf4q\nK2XkH/9IzYg6d6670+2ii8JCC8GECenrF16Aiy6C++9Pz0uSpGx88gmcfDK0bZtuGL/1liFUaipn\nRKUCGj8eeveGHj1SK/cXX6w/VM5YnnvbbWm5zwMPQJs2hatXkiSlI1gGDoSXX04fAwemY9NGjUrn\nfktquhBjzOYHhxCz+tlSFt57D7bYIjUyOOSQ1GxogQXqf88f/gCHHQZnnAGjRzvYSfUJIRBj9CTd\nPDg2SzNNnpxWId1zT+pu37YtbLcdbL89VFXB0ktnXaFU/Oobmw2iUoH86U/paJbq6sa/5/DDYcAA\naN8e7ryzxUqTyoJBNH+OzVLaEnPnnXDLLbDRRnDaabDjjrDYYllXJpWe+sZml+ZKBfDZZ/DII2lW\ntClWWQXefRd69WqZuiRJUvL99+lmcZcusPvu0K9fCqKSWoZBVGpBMcLrr8MVV8CRR8JyyzXt/auu\nmpbzbrJJi5QnSZJIPRx23RU22ACGDYPVV8+6Iqn82TVXaiE33AC//W06omWbbZq2JHeGQw+Fnj2b\nvTRJmqvq6mpyuVzWZUgF88knad/nrrvCvfcaQqXmkMvlqG7gl1/3iEotoHdv+Mtf0uff/a7u41kk\nNS/3iObPsVmV5p13oFMnOOectBdUUvOyWZFUQJ9+Cu3awZNPwuabZ12NVDkMovlzbFYlee012Gef\ntILp4IOzrkYqTzYrkgrk66/TndXzzzeESpKUtUGD4KWX5nx+0iS4+Wa47z7YZZfC1yXJICo1iwce\ngL5904C3995w1llZVyRJUuWaNAkuvhh69IADDoD55pvzmiefTA0BJWXDpblSnoYOhZ12gmuugRVW\nSC3f3RMqFZ5Lc/Pn2Kxy8NxzcNxxqVHgjTemsVlSNtwjKrWQCRNg223TUtzDDsu6GqmyGUTz59is\nUvbNN3D22fDCC3DnnS65lYpBfWOzx7dI86CmJh10vfHGaaA79NCsK5IkqXI98gi0bQtLLAFvv20I\nlUqBe0SlJogRunRJZ4IutRTcfjvstlvWVUmSVJlihCuuSGPzQw+l5biSSoNBVGqk6dNTe/dRo9Kd\n1802y7oiSZIq15QpcPzxaQb0tdfgV7/KuiJJTWEQlRrp6qth/Hh44w1YaKGsq5EkqXJNnAj77QeL\nLAK5HCy2WNYVSWoqg6hUj6lT4cEHYdy4dN7YoEGGUEmSsjRmDOy6K7RvDzfdVPfRLJKKn0FUmovp\n0+HII+H991MDhJ49YfXVs65KkqTKNWQI7LFHOq/7zDM9Lk0qZQZRaS7OOgvGjk1LfhZZJOtqJEmq\nXD/8AE88AaedBnfcAf/3f1lXJClfBlGpDn36wOOPw9ChhlBJkgpp2jR45x0YMCD1ZRgwAD78MB2Z\n1qcPbL111hVKag4hq4OrPTRbxWj6dOjfP3XHffhh2HbbrCuS1Fj1HZqtxnFsVqFNnw7vvZd6MAwe\nDAMHpuW3q60GW24JW2yRPm+4ISy4YNbVSmqq+sZmg6gEfPEFXHcd9OoFK60EZ58NhxySdVWSmsIg\nmj/HZrWkadNg9OgUOmcEz6FDYcUVYdNNoV27dDTa5puns7ollb76xmaX5krA6aenJbjPPQdt2mRd\njSRJ5eXFF2GffVLobNcuBc+99oJNNoFllsm6OklZcEZUFe/dd2G77dL+k8UXz7oaSfPKGdH8OTar\nJbz3Xhpne/aE3/8+62okFVJ9Y3OrQhcjFZvOneHkkw2hkiQ1t2+/hd13h8svN4RK+iWX5qoi/fBD\n6orbo0dqjDByZNYVSZJUXqZOhQMOgF12geOPz7oaScXGGVFVnP79YfXVoXt3OOgg+OADWHbZrKuS\nJKm8nHkmzD9/agYoSbNzRlRl5dJLYb/9Upv3unz7LRx2GNx/P+y6a2FrkySpUtx+O7zwArz2Wgqj\nkjQ7/9OgsjFuHFx5JSy/fN1BdPp0OOYY2HtvQ6gkSS3l2WfhiivgP//xGBZJc2cQVdno0gUWXhhG\njZrztRjhhBPSjGiPHoWvTZKkSjBqVDqH+6GHYM01s65GUjFzj6jKQk0N3HUXXHBB3UH06qth2LDU\noGjhhQtfnyRJ5e6bb2CPPeCqq2CHHbKuRlKxM4iq5E2bBhdfnJbkHnronB1wBw6EG2+Ehx+GJZbI\npkZJksrZ1KmpR8Nee6VtMJLUEJfmqqRNmQIdO6ZGCI89BiuvDN99BxMnpn0p77wDf/xjapqw+upZ\nVytJUvmJEU45BRZdFK65JutqJJUKg6hK2iWXpFnOxx6DVrXz++uum5bnjh0Lxx0HnTvD/vtnW6ck\nSeXohx/gttvg1VdTc6L55su6IkmlwiCqkvXcc9CtGwwdOjOEAqy3Xlqe27kz9OoFHTpkV6MkFYsQ\nwm+Ai4AlY4wHZF2PSs8PP8CQIfDmmzBoUPoYMwY22QT69oUll8y6QkmlJMQY678ghHuA3YFxMcaN\nap9bBngAWAP4GDggxjix9rVbgF2AScCRMcahc/m+saGfLc3NG2/A7rtD795QVfXL1/76V3jqKZgw\nIS3NDSGTEiUVWAiBGKP/j29ACKH33IKoY7NmmFvo3HBDaNdu5sf668MCC2RdraRiVd/Y3JgZ0S7A\nrcB9szx3PvBcjLFzCOE84ALg/BDCLsCaMca1QwhbAncCW+VXvvRLH38Me+4J99wzZwiFNCN68cVw\n882GUEnlq64bxbXPdwJuIjUkvCfG6K49zdX06fDBBzB8OLz1Vvo8fHja3jIjdHboAOeeC23aGDol\nNZ8GZ0QBQghrAH1nmREdBewYYxwXQvgV8GKMsU0I4c7axw/UXjcSqIoxjqvje3rXVU02fXoKn3vu\nCeecU/c1I0emgfPzz2GZZQpanqQMVdqMaAhhO+AH4L5ZxudWwLtAB2AsMBD4Y4xx1CzvezDGWOfO\necfm8jZ+/MygOSN0jhgBK62UQudGG6XPG24Ia6+dGgFKUj7ynRGty4ozwmWM8csQwoq1z68KfDrL\ndZ/XPjdHEJWaavhwuOEGWHBBOPvsuV+33nppSa4hVFI5izG+UnujeFZbAO/FGD8BCCH0AvYCRoUQ\nlgX+BmwcQjjPmdLyV1MD//wnPPRQGkOnTJkZNLfaCo49Ftq29WgzSdlo7ntddaXdud5ara6u/vlx\nVVUVVXWts1TFu/deuP76dCTLQQel1vCt6jkBNwT4zW8KVp6kjORyOXK5XNZlFJvZbwh/RgqnxBi/\nAU5s6Bs4NpeHDz5I53lOmQIXXQS/+x2suqpbViS1rKaMzfO6NPfnJbcNLM39eQlvHd/T5T9q0Ixu\nfI88AttvX38AlVTZKm1pLtQ5Pu8H7BxjPK7260OBzWOMpzfy+zk2l7iaGrj1VrjiihRATzvNI1Uk\nZac5luYGfjnb+ThwJHBN7ec+szx/MvBACGErYEJdIVRqrOuuS3d0d9wx60okqSR8Bvx6lq9XI+0V\nVQV47z04+uj0+LXX0j5PSSpWDc4vhRB6AK8C64QQxoQQjgKuBnYKIYwmNUS4GiDG+BTwUQjhfeAu\n4KQWq1xlb/x46N4dzjwz60okqWjNfqN4ILBWCGGNEMKCwB9JN4lVxqZPTz0Utt4a9t8f+vc3hEoq\nfg3OiMYYD57LS3+Yy/Wn5FWRKtq0afDCC9CjB/TpA6ecAiuvnHVVklR8am8UVwHLhRDGAJfGGLuE\nEE4F/s3M41tGZlimWtioUWkWdMEFYcAAWHPNrCuSpMaxMbeKRoyw777w6adwxBFw1VWGUEmam7nd\nKI4xPg08Pa/ft7q62iZFJWDGLOg118Dll8MJJ9hHQVLxaEzTokY1K2oJNkTQ7P7+d/jXv+DVV9Od\nXUlqikpsVtTcHJtLw4gRcNRRsPjicPfddoqXVLzqG5u9d6ai8MYbcOmlaUmuIVSSpDlNm5ZWC+24\nY1qO+9xzhlBJpculucpMjPDRR2kp7gEHQJcusM46WVclSVLxefvtNAu6zDLw5puwxhpZVyRJ+XFG\nVJm56CLYcks49th05tnuu2ddkSRJxWXqVPjrX6F9ezj+eHjmGUOopPLgjKgy0b8/3HsvvPMOrLhi\n1tVIklRcamrg0UdTI6JVVoHBg2H11bOuSpKaj0FUBffii3DIIanBgiFUkoqLXXOzNXUq9OyZ9oIu\nuWQKonvuCcE2XJJKiF1zVTRiTMuJ7rsvzYbecw906pR1VZLKiV1z8+fYnJ2ffkq9Ejp3Tg2ILroI\nfv97A6ik0lbf2OyMqFrcV1/Bn/4EH3wAJ54It9+emi1IklTpvv8e7rwTbrwRNtssdY/feuusq5Kk\nlmcQVYv66Sfo0AF22gkefNCjWSRJAvjmG7jllnRz9g9/gH79YKONsq5KkgrHrrlqUeefD+uuC9dd\nZwiVJOmLL+Ccc2DtteGzz+DVV9OeUEOopErjjKia3ddfwz77wMcfp70tQ4e6x0WSVNk++giuvRZ6\n9YLDDktjo11wJVUyZ0TVrCZOTE2Itt023eUdORKWXTbrqiRJjVVdXd1gp0M13siRcPjhsPnmqT/C\nqFFw882GUEnlLZfLUV1dXe81ds1Vs4kR9t8fllsuNV5wFlRSIdk1N3+Ozc1n0CC48kp45RU4/XQ4\n6SRYeumsq5KkwrJrrgqiSxd47z3o3t0QKkmqTC+9lALoO+/An/+cji1bbLGsq5Kk4mMQVV6mTEmd\n/nr0gGefTQPwwgtnXZUkSYU1eDCccQaMHZsa9fXpAwstlHVVklS83COqeTZqFKy2Glx/PbRvD+++\nCxtskHVVkiQVzrffwsknw667pr2go0als7MNoZJUP4Oo5tmVV8Jpp0H//nD88WlvqCRJlaCmBv71\nL2jTJvVIGDEiBdD5XWsmSY1isyJRU5M+t2rCbYmPP4Z27eCDD2y+IKk42Kwof47NjTN4cJoFjRFu\nvz2Nh5KkOdU3NjsjKq68Mh2u3VhjxqQGDH/6kyFUklQ5vv0WTjkFdtkljYGvvmoIlaR5ZRCtcFOn\nwt//DqNHN3xt9+6www6wySbpbNDzzmv5+iRJheU5onOqqUmd4du0genT09mgxxzTtJVEklRJPEdU\nDXr0UTjxRFh+eXj77blf98gjaRb0ppugY0ebMEgqPi7NzZ9j85yGDEnLcKdPT8twN9ss64okqXTU\nNzYbRCtcx46w555pdvP77+s+//Pzz9PSoz59YMstC1+jJDWGQTR/js0zTZgAF18MvXvD3/4GRx/t\nDKgkNZV7RDWHSZPSTOgHH6TlRQssAN98M+d1EyfCXnul7riGUElSuaupgXvvTctwp06d2Q3XECpJ\nzcsm4xVo+vQ0C7riijBoECy8MLRunTrhznoEy08/we67w9ZbwwUXZFWtJEmFMXRoWoY7dSr07esy\nXElqSd7fq0DXX58G2e7dYaml0nNrrAGffPLL6y68EFZYAW6+ue4lu5IklYMJE+DUU9N2lSOPhNdf\nN4RKUktzRrTC9O8P110HAwfCfPPNfH7GjOgMzzwDDz4Iw4a5HEmSVJ5qaqBbNzj//LQNZcSIX64M\nkiS1HINoBXnjDdh/f+jVK82Azqp1a/jwwzQo33QTXHVVCqLLLptJqZIktahhw9Iy3MmT4fHHYfPN\ns65IkiqLc10VYvx42HtvuPtu+P3v53x9xtLcnj3TWWkDBkBVVcHLlCRlrNzPEZ0wAU4/HXbeGQ4/\nPC3DNYRKUvPyHFEBEGNqTtS2bZrprMuQIWlfzBJLpPNC9967oCVKUt48viV/5Tw2x5iW4Z53XhoT\nr7zSZbiS1NI8R7RCffcdPPYY3HdfOoblP/+BBRes+9pvv01ddFdaKe0Vnd9F25JKjEE0f+U6Ng8b\nBqeckrrB3347bLFF1hVJUmXwHNEKdNddsPrq8PDDcOyxqUnR3EIowNJLwyKLpLPSDKGSpHIwcWJa\nhrvTTnDYYWkZriFUkoqDkaMMTZoEF1+cZkDbtm3ce0KA445LH5IklbIY0xFl552XzsMeMQKWXz7r\nqiRJs3Jpbhm66SZ4+eU0GypJlcKlufkr5bH5k0/S2PfSS5DLpXOyXYYrSdlyj2gFeecd6NQJHn3U\nw7glVRaDaP5KZWyOEUaNSqFzRvicPBl22AG23z593mgjz8GWpKzVNza7NLcMTJoEt90GPXrAN9/A\nSScZQiVJ5WPatNRwaEbwfPnl1OV9++2hfXu45BJYe+20zUSSVBqcES0Dhx8O//1v2guz3XbeAZZU\nmZwRzV+xjM0//QRvvDEzdL72WmrAN2O2c/vtYbXVsq5SktQQZ0TLWM+eMHAgDBoEiy6adTWSJDXd\nd9/Bq6/OXGY7ZAisv34KnCeemBoP2WxIksqLM6IlbOBA2G036NcPNt0062okKVvOiOavUGPzV1/N\nnO186SUYPTptKZkx27n11rD44i1ehiSphTkjWkZqaqBbt7QX9Jpr4J57DKGSpOZTXV1NVVUVVVVV\nzfY9Z3S0nRE8v/gCttkmBc9bbkkhdKGFmu3HSZIylsvlyOVy9V7jjGiJufbatERphx1Sd9zddsu6\nIkkqDs6I5q85xuYZHW1nhM6XX057Pmfd37nRRjDffM1UtCSpaHl8S5kYPDiFz4EDYY01sq5GkoqL\nQTR/8zI2z+hoOyN4vvIKLLbYL4PnOuvY0VaSKpFBtMTFCL17w6mnpsO5998/64okqfgYRPPXmLH5\np5/SDdEZs52vvZY62M4IndtvnzrcSpJkEC1R06bBrbfC3Xenr7t29XxQSZobg2j+6hqbv/8+dbSd\nETwHD4Y2bWYGz+22s6OtJKluBtES9NlncMABaXnTZZelDoIua5KkuTOI5i+EEMePj7zyyszgOWoU\ntGv3y462SyyRdaWSpFJgEC0x06alAb9DhxRCW7XKuiJJKn4G0fyFEOKSS8afO9puvz1svrkdbSVJ\n86bFgmgI4WNgIlADTI0xbhFCWAZ4AFgD+Bg4IMY4sY73GkRnM2kSfPRR6oo7aBA884whVJIayyCa\nvxBCnDYt2tFWktQsWjKIfgi0izF+O8tz1wD/jTF2DiGcBywTYzy/jvcaRGfx9dew444wfTosuyw8\n9BCsskrWVUlS6TCI5s+xWZLUnOobm/Odbwt1fI+9gK61j7sCe+f5M8reDz+kY1n23DPtxXn1VUOo\nJEmSpPLVHDOi3wARuCvGeHcI4dsY4zKzXPPfGONydbzXu661jj02tcO/7z4bEknSvHJGNH+OzZKk\n5lTf2Dx/nt97mxjjlyGEFYB/hxBGk0KpGiFG6NEDXngBhgwxhEqSJEmqDHkF0Rjjl7WfvwohPAZs\nAYwLIawUYxwXQvgVMH5u76+urv75cVVVFVVVVfmUUzI+/BC6dUshdPp06NkTllwy66okqbTkcjly\nuVzWZUiSpHkwz0tzQwiLAq1ijD+EEBYD/g1cBnQAvokxXmOzojl98w2ssw4ceigcfHBqi+9MqCTl\nz6W5+avUsVmS1DJaamnuSsCjIYRY+33ujzH+O4TwJtA7hHA0MAbYP4+fUXZuuy01JbrppqwrkSRp\nTtXV1RW1SkmS1Pwas2opr2ZF+ajEu64//AC/+Q288gqsu27W1UhSeXFGNH+VODZLklpOSx7fokaY\nMgX69oUDDoCqKkOoJEmSpMpmEG1hN9yQzgTt3Bn22APuuSfriiRJkiQpW/ke31KxvvsOHnoIjj56\n7tc8/zxcfz0MGABrrlm42iRJkiSpmDkjOo/uvRfOOiudBVqXr7+GI4+ELl0MoZIkSZI0K4PoPIgR\n7rwTvv8exo2b8/WJE6FjxxREd9654OVJkiRJUlEziM6Dl19On7fZBkaO/OVr06bB3nvD1lvD5ZcX\nvjZJkiRJKnYG0SaaNAmuuAJOOAHatIFRo375+lVXQatWcMstEDxEQJIkSZLmYBBtgnffhU02gdVW\ng2OPhfXW++WM6DPPwG23wX33pTAqSZIkSZqTcamRJk+GAw+EU05JDYgWWSQF0RkzohdemDroPvAA\nrLpqtrVKkiRJUjHz+JZGuugiaN0aTj115nMzlua++Sb06AFDh8IKK2RWoiRJkiSVBINoI/z97/DI\nI/DGG7/c9/nrX6djWq67Lu0ZNYRKkiRJUsNCnNtBmC39g0OIWf3spujdG84+G/r3h9/+ds7XN944\n7RMdMwZWWqnw9UmSkhACMUbbxOWhVMZmSVJpqG9sdka0Hh99BCefDM8+W3cIhbRPdL31DKGSJEmS\n1FgG0bn4+GM45BC44II06zk3554LSy1VsLIkSZIkqeS5NHcWU6bAP/+ZGg+9+y4ccQR07uxRLJJU\nClyam79iHJslSaXLpbmNdOutaU/opZfCTjvBAgtkXZEkSZIklR9nRGtNnpz2gT75ZP1LcSVJxckZ\n0fwV29gsSSpt9Y3NLjqt1bUr/O53hlBJkiRJamkVvTQ3RhgwIO0Jvf9+ePzxrCuSJClb1dXVVFVV\nUVVVlXUpkqQSlcvlyOVy9V5TsUtzv/wS2rdPYfTgg9PHWmtlVo4kKU8uzc1f1mOzJKm81Dc2V2QQ\nramBXXeFTTeFv/0Ngr+2SFLJM4jmzyAqSWpO7hGdzY03wrffwmWXGUIlSZIkqdAqbo/offelIPry\nyx7PIkmSJElZqIggOnky7LILDBuWwucLL8BvfpN1VZIkSZJUmSoiiF58MSy5JLz7Liy2GCy8cNYV\nSZIkSVLlKvsget996WiWYcNgueWyrkaSJEmSVJZBtOb/27vXWLmqKoDj/4WEJhVCUAQjFeQtmpBi\ngKDGBGN5JlBBEKyglJiC9ALBL4IY+MgjaBQBBUEsRh7FpAKlQmMIEmt4PwoUsRBe1VBp0IBKeLTL\nD+eUXm5n5j5m5pwzd/6/pMm9p2furK6uO2fW7L3P3gArVsDll8NTT8GyZbD99nVHJUmSJEmCadiI\nPvccnHQSvPkmnHwyLFoEM2fWHZUkSZIkaaNp1Yg+8QTMmQMXXAALF8IWQ7k5jSRJkiQ1W9S1cXWv\nNyv95IAAAAj7SURBVM1+6y3Yf38499xiJFSSNFw6bZqtien1tVmSNNw6XZsHfkT04Yfh0kvhpZdg\n332LabmSJEmSpOYa6BHRlSvhkEPg/PNh1iw47LBiexZJ0vBxRLR7johKknqp07V5YBvRdetgv/3g\nssvghBN6GJgkaSDZiHbPRlSS1EvTrhHNhGOOgb32KqblSpJkI9o9G1FJUi9NmzWiGzbAfffBddcV\na0JvuaXuiCRJkiRJkzUwG5zccAPsvDOcc05xU6Lly2HGjLqjkiRJkiRN1kBMzX3jDdhtN1i6FA46\nqM+BSZIGklNzu+fUXElSL3W6Ng/EiOjVV8OcOTahkiRJkjQdNH5EdN26YirusmUwe3YFgUmSBpIj\not1zRFSS1EsDNyL6zjtw001w1FGw++4wb55NqCRJkiRNF40cEZ0/H559Fs44A+bOhW22qTg4SdLA\ncUS0e46ISpJ6aaC2b1m8GFasgEcfha23rjsaSZIkSVKvNaoRXbkSRkbgzjttQiVJkiRpumrMGtHV\nq+GII+CKK+CAA+qORpIkSZLUL41YI/rWW0XzOTICp59eSziSpAHnGtHuuUZUktRLna7NjWhEzzoL\n1q6Fm2+G8C2EJGkKbES7ZyMqSeqlxt6s6O234fzzYelSeOQRm1BJkvolImYCVwFvA3/KzBtrDkmS\nNMT6tkY0Ig6PiL9GxN8i4vutzjn+eHj+eXjwQdhuu35FMv3ce++9dYcw0Mzf1Jm7qTN33TF/PXEs\ncGtmngYcXXcw0lT4WqAmsz4npy+NaERsAVwBHAZ8FvhGRHx67Hn3319Mx91++35EMX1Z5N0xf1Nn\n7qbO3HXH/G0uIq6LiLURsXLM8XYfBM8CXim/Xl9ZoFIP+VqgJrM+J6dfI6IHAqsz86XMfBe4GZg7\n9qRTToEZM/oUgSRJ09v1FB/4vm+cD4JfoWhGAab9Ypi63hD243m7/ZlTefxkHzOR83t1znRgfXb/\n+Mk8bqLnjnfesNQnVPNv7VcjuhObPnUFWFMe+4AFC/r07JIkTXOZ+WfgX2MOd/ogeAlwXERcCdxR\nXaT18I1+d4+3Ee0v67P7x9uI9lcV/9a+3DU3Io4DDs3MBeX3JwEHZObZo87xtnySpJ4atrvmRsQu\nwB2ZuW/5/deAw8Zcfw/MzLMm+PO8NkuSeqrqu+auAXYe9f0s4B8TCUiSJE1Zq2vrhJtLr82SpKr0\na2ruQ8AeEbFLRGwFnAjc3qfnkiRJhXE/CJYkqQn60ohm5npgBFgOPA3cnJnP9OO5JEkaYsEHR0H9\nIFiSNBD6skZUkiT1V0TcCBwMfBRYC1yYmddHxBHATyg+bL4uMy+uL0pJklrr19TcjjrscaYWIuLF\niHgiIh6LiAfLY9tFxPKIeDYi7o6IbeuOswla7avXKVcRcXlErI6IxyNidj1RN0eb/F0YEWsi4tHy\nz+Gj/u68Mn/PRMSh9UTdDBExKyLuiYhVEfFkRJxVHrf+xtEid2eWx629DjJzXmZ+IjNnZObOmXl9\nefwPmbl3Zu5pEypJaqrKG9Fx9jhTaxuAgzNzv8w8sDx2LvDHzNwbuAc4r7bommWzffVok6ty1GD3\nzNwTOA34RZWBNlSr/AH8ODM/V/65CyAi9gG+DuwDHAFcFRHDfKOT94DvZeZngM8DC8vXNutvfGNz\nNzLqumDt1SwiZkbEryPi6oiYV3c80mgRsWtEXBsRi+uORWolIuZGxDURsSQiDqk7niapY0S00x5n\nai3Y/P9qLrCo/HoR8NVKI2qoNvvqjc3V3FHHbygf9wCwbUTsWEWcTdUmf9D6TpxzKdZ/v5eZLwKr\nKX6/h1JmvpqZj5df/wd4huJGMdbfONrkbuPe09Ze/Y4Fbs3M04Cj6w5GGi0zX8jM79Qdh9ROZt5W\nbqk1n+JDVJXqaER3Al4Z9f0aNr3hUGsJ3B0RD0XExhfbHTNzLRRv4oCP1RZd8+0wJlc7lMfH1uLf\nsRbbWVhOH7121NRS89dGRHwKmA3cz+a/q9ZfB6Ny90B5yNrrsVZT8Mvj7ZbNzGJTvtdXFqiG0hTq\nU6pUFzX6Q+DKaqIcDHU0ol3tcTakvpCZ+wNHUrwp+xLmrBesxYm5imIK6WzgVeBH5XHz10JEbA38\nDji7HN1rlxPzN0aL3Fl7/bHZFPxxls28QtGMQuvcS7002fp8/7RqwpMmX6MRcTGwbOPsHxXqaETd\n42ySylEUMvM14PcUU9DWbpzGFxEfB/5ZX4SN1y5Xa4BPjjrPWmwhM1/LTbfX/iWbpkCavzEiYkuK\nRuo3mXlbedj6m4BWubP2+qPNFPxOy2aWAMdFxJXAHdVFqmE02fqMiI9ExM+B2Y6UqgpTqNEzga9Q\nvI4uqDTYhqujEXWPs0kobxKxdfn1h4FDgScpcnZKedq3gdta/oDhNHZfvdG5OoVNubod+BZARBwE\n/HvjFMoh94H8lc3TRscCT5Vf3w6cGBFbRcSuwB7Ag5VF2Uy/AlZl5k9HHbP+Jmaz3Fl7lWq7bCYz\n/5eZp2bmwsy8qZboNOw61efrmfnd8i7Rl9QSndS5Rn+WmQdk5hmZeU0t0TXUllU/YWauj4gRYDmb\n9jh7puo4BsiOwJKISIr/r99m5vKIeBhYHBGnAi8Dx9cZZFPEqH31IuJl4ELgYuDWsbnKzGURcWRE\nPAf8l2IR+VBrk78vl1uLbABepLjDK5m5qrxL4SrgXeCMUaNXQycivgh8E3gyIh6jmCr6A+ASWvyu\nWn+bdMjdPGuvMk53VpNZn2o6a3QKKm9EAcpb8O9dx3MPmsx8geLGHWOPvw7MqT6iZsvMdlsLtMxV\nZo70MZyB0yZ/13c4/yLgov5FNDgycwXwoTZ/bf110CF3d3V4jLXXWy6bUZNZn2o6a3QK6piaK0mS\n6jV2CYPLZtQk1qeazhrtARtRSZKGSDkF/y/AXhHxckTMz8z1wJkUy2aeptin1WUzqpz1qaazRnsn\nXFYjSZIkSaqSI6KSJEmSpErZiEqSJEmSKmUjKkmSJEmqlI2oJEmSJKlSNqKSJEmSpErZiEqSJEmS\nKmUjKkmSJEmqlI2oJEmSJKlSNqKSJEmSpEr9H0yxaXK/EQB8AAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x72df4cb4a748>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def improved_bitslide1(nbits, offx_lsb, cutoff):\n",
+ " bs = sorted(bitslide(cutoff, offx_lsb))\n",
+ " return [ sum((2**n + offx_lsb) if i&(2**n) else 0 for n in range(cutoff, nbits))\n",
+ " + bs[i%(2**cutoff)] for i in range(2**nbits) ]\n",
+ "\n",
+ "plot_bitslide(improved_bitslide1(8, 2.5, 5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAF2CAYAAAB0yCWXAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XeYlNXZx/HvQTH2rrFX7CWoETUaXbsYo4k92FsSW+yx\n5I2sGAuWxN5RwYJYgxBBVJwYkyiiQFRAkYiFZqwoFsqe948zKiLsLjvlmfL9XNdezD77zO6PyYbj\nPeec+4QYI5IkSZIklUu7rANIkiRJkuqLhagkSZIkqawsRCVJkiRJZWUhKkmSJEkqKwtRSZIkSVJZ\nWYhKkiRJksrKQlSSJEmSVFYWopIkSZKksmqxEA0h/CCE8HwIYVgI4eUQQtf89TVCCM+FEF4LIfQO\nIcyfv75ACOG+EMKYEMK/QwirlfovIUmSmhdCWD+EcGMI4f4Qwm+zziNJqm8tFqIxxq+AHWOMmwEd\ngc4hhK2A7sCVMcb1gI+BY/JPOQb4MMa4DnAVcFlJkkuSpFaLMY6OMR4PHARskXUeSVJ9a9XS3Bjj\n5/mHPwDmByKwI/BQ/npP4Bf5x/vkPwd4ENi5KEklSdI3Qgg9QgiTQwj/me36HiGE0SGE10MIZ8/2\ntZ8D/wCeKmdWSZJm16pCNITQLoQwDJgEPAGMBT6OMTblb3kXWDn/eGXgHYAY40zg4xDC0kVNLUmS\n7gB2n/VCCKEdcF3++kbAr0II63/99RhjvxjjdsCh5QwqSdLs5m/NTfmCc7MQwuLAI8AGc7ot/2eY\n7XqY5WuSJKkIYozPhhBWn+1yJ2BMjPEtgBDCfaSVSqNDCDsA+5JWN/2trGElSZpNqwrRr8UYp4QQ\n/g5sDSwZQmiXL1JXASbkb3sXWBWYEEKYD1g8xvjR7N8rhGBxKkkqqhjj7G+G1ptvViXlvUsqTokx\n/h34e3NPdmyWJBXb3Mbm1nTNXTaEsET+8ULALsBI4GnggPxtRwB9848fzX9O/uuDmwnlRxs+unbt\nmnmGav7w9fO187Wrvo/WvH4Cvr8qCeZxVVLW/1uX83emWn5uod+zLc+f1+e05v5i3FMr/5b6+1n4\n8+flea29t9Dfv1r5/Szm36U5rZkRXRHomd930g7oE2N8LIQwCrgvhHAhMAzokb+/B3BXCGEM8AFw\n8LwMgJIkqc3eBWY9Nm3WFUt1paGhoWZ+bqHfsy3Pn9fntOb+Yt1TC/z9LPz58/K81t7b0n318vsJ\n5fm7tliIxhhfBjafw/U3ga3mcP0r4MCipJMkSc0JfHcW9AWgQ37v6ETSm8G/yiJY1vwP/cKebyFa\nWv5+Fv58C9HSKsfftVVdc1VZ6un/BKXg69d2vnZt52tXGF+/7wsh3Av8C1g3hPB2COGomLrVnwwM\nAl4F7osxjsoyp1RM/lugSubv57wJLa3dLdkPDiFm9bMlSbUnhEC0WVFBQgixa9euNDQ0+B9UkqQ2\ny+Vy5HI5LrjggrmOzRaikqSaYCFaOMdmSVIxNTc2uzRXkiRJklRWFqKSJEmSpLKyEJUkSZIklZWF\nqCRJ+kZjYyO5XC7rGJKkKpbL5WhsbGz2HpsVSZJqgs2KCufYLEkqJpsVSZIkSZIqhoWoJEmSJKms\nLEQlSZIkSWVlISpJkiRJKisLUUmSJElSWVmISpKkb3h8iySpUB7fIkmqGx7fUjjHZklSMXl8iyRJ\nkiSpYliISpIkSZLKykJUkiRJklRWFqKSJEmSpLKyEJUkSZIklZWFqCRJ+obHt0iSCuXxLZKkuuHx\nLYVzbJYkFZPHt0iSJEmSKoaFqCRJkiSprCxEJUmSJEllZSEqSZIkSSorC1FJkiRJUllZiEqSJEmS\nyspCVJIkSZJUVhaikiTpG42NjeRyuaxjSJKqWC6Xo7Gxsdl7QlYHV3totiSpmJo7NFut49gsSSqm\n5sZmZ0QlSZIkSWVlISpJkiRJKisLUUmSJElSWVmISpIkSZLKykJUkiRJklRWFqKSJEmSpLKyEJUk\nSZIkldX8WQeQJGlexQgvvQQTJkD79rDHHlknkiRJ88JCVJJUNcaOhZ494d57oV07WG89WGQRC1FJ\nkqqNhagkqSq8+SZsvTUcdhjcdx9ssQWEkHWq2tPY2EhDQwMNDQ1ZR5EkValcLkcul2v2nhBjLE+a\n2X9wCDGrny1Jqi4zZsAOO8B++8Hpp8/5nhACMUZL0wI4NkuSiqm5sdlmRZKkivXii7DyyrD44unj\n1FOzTiRJkorBpbmSpIoycyb84x/wwQdw4olw/fWw++6w8MJpX6gkSap+FqKSpIrSvTv06AEdOsC1\n16bluJIkqba4R1SSVDFeeAH22guGDoVVV52357pHtHCOzZKkYnKPqCSp4g0YAPvsk5bizmsRKkmS\nqkuLhWgIYZUQwuAQwsgQwsshhJPz17uGEN4NIbyU/9hjluecG0IYE0IYFULYrZR/AUlS9bviCvjN\nb+Cee2D//bNOI0mSSq3FpbkhhBWAFWKMw0MIiwIvAvsABwGfxhj/PNv9GwD3AlsCqwBPAuvMvtbH\n5T+SVN8++giGDYPnn4dbb00NilZeue3fz6W5hXNsliQVU3Njc4vNimKMk4BJ+cefhRBGAV//p8Kc\nvuk+wH0xxhnAuBDCGKAT8HxbwkuSas/06akTbgiw7LLw5JOFFaGSJKm6zNMe0RDCGkBHvi0qTwwh\nDA8h3BZCWCJ/bWXgnVmeNp5vC1dJUh1raoJp0+CCC2CZZeC55+Bvf4O11so6mSRJKqdWH9+SX5b7\nIHBKfmb0BqBbjDGGEP4EXAkcy5xnSee4zqexsfGbxw0NDTQ0NLQ+uSSpqnz4Iey8M7zyCqyyCvz7\n32lGtK1yuRy5XK5o+SRJUvm06viWEML8QH9gQIzx6jl8fXWgX4xx0xDCOUCMMXbPf20g0DXG+Pxs\nz3EfiiTViU8/TUXoDjvAZZcVVoDOjXtEC+fYLEkqpmIc33I7MHLWIjTfxOhr+wKv5B8/ChwcQlgg\nhLAm0AEYMu+xJUm14uSTYf31S1eESpKk6tLi0twQwrbAIcDLIYRhpGW25wFdQggdgSZgHPAbgBjj\nyBDC/cBIYDpwgm+vSlL9mTEDJkyAp56Cf/0LXnrJIrQaNDY2ul1GklSQ1myfadXS3FJw+Y8k1Z6v\n/1kfORIOPRQmTYJFF4XeveHHPy7tz3ZpbuEcmyVJxVSMpbmSJLXomGOgXTvYZhs44YQ0IzpmTOmL\nUEmSVF1a3TVXkqTmvP469OsHU6bAYotlnUaSJFUyZ0QlSUVx2WVpFtQiVJIktcQZUUlSm332GVx4\nIYwbB088kZbhSpIktcQZUUlSm4waBR07wnvvwS9/CYMGwTLLZJ1KkiRlKUa46y7YZ5/m77NrriRp\nnn3xBXTqlJbiHn981mkSu+YWzrFZklSICRNSAfrBB2nF1KGH2jVXklQE48dD376p+NxwQ/jtb7NO\nJEmSKsEtt8Aaa8Cee6YGhocc0vz97hGVJLXKuHGw/faw8caw1FJw000QnH+UJKmuvfJKOr5t/Hh4\n9tm0Yqo1nBGVJDXrppvg8MOhoQHOOgseewzuuScVo5IkqT59+SVceSVsuy3suCOMHdv6IhTcIypJ\nasYTT8DRR8Of/gQrrQS77pp1orlzj2jhHJslSa3x4INwySVpZdR118HWW8/5vubGZgtRSdIcTZiQ\n3tns2RN23jnrNC2zEC2cY7MkqSXPP58KzzvvhC5doH37ud/b3NjsHlFJEpAGlg8/TI8nTIA//AHO\nPLM6ilBJklRaM2fCjTfC1VdDt25wxBGFfT8LUUkSL72Uutx9vbejfXt46KG070OSJNW3MWNgr71g\nvvlSMbrjjoV/T5fmSpL49a9Ty/Xzzss6Sdu5NLdwjs2SpFk1NcHFF6f9oJddlo5tm2++1j/fpbmS\npLn65BN44AEYNSrrJJIkqVL8/e9w0UXw3nvwzDOwxRbF/f4e3yJJderLL6FXLzjnHNhlF1hhhawT\nSZKkrMUIf/lLWn67006pIC12EQrOiEpS3erbFy68EH76U7jggqzTSJKkrA0bBkceCVOnpv4RHTuW\n7me5R1SS6tSRR8KWW8KJJ2adpDjcI1o4x2ZJqk8zZqTZzxdfTGeHn3IKtCvC2tnmxmaX5kpSHWpq\ngoEDoXPnrJOo0jQ2NpLL5bKOIUkqgxjhySdhm23giy/g/ffhtNMKL0JzuRyNjY3N3uOMqCTVoWHD\n4KCD4PXXs05SPM6IFs6xWZLqxyuvwB//CMOHw1FHpZ4RCyxQ3J/hjKgk6TsGDHA2VJKketTUBPff\nDw0NsO66MGQInH9+8YvQltisSJLqwMyZkMvBvfemdz7ffBN69846lSRJKqfJk6FLFxg9OjUt3Hbb\n7LI4IypJNa5XL1h1VTj7bNhoI7jpJhg8GHbdNetkkiSpHL74Ai65BDp1gvXWS2eHZ1mEgntEJamm\n/ec/sPPOMGgQbLZZ1mlKyz2ihXNslqTa8/bbcMQR8OGHcOmlsMceEMo0WrpHVJLqzOOPw5VXwsEH\npz9rvQiVJEnf9cUXcNll6b8BNt88rYbq3Ll8RWhLnBGVpBrTuzeceWYqQtdYA046qXIGnVJyRrRw\njs2SVP1ihOuug0cfhU8+ge7dU2OiLP5boLmx2WZFklQDvvwSDj88Lb8ZNy6dCbbxxlmnkiRJ5Xbx\nxXDHHek80GOOgQUXzDrRnDkjKkk14LTTUgH6+9/D6qvDSitlnaj8nBEtnGOzJFW3996DH/4Qnn8+\nNSbKmjOiklTD7r8fHnwQRoyApZfOOo0kSSq3r76Cc86Bq66CY4+tjCK0JRaiklSlpk+HU0+Fv/0N\nHn7YIlSSpHrUs2cqQtddFyZOhBVWyDpR61iISlIVmjkz7Qn95JM0E7rEElknkiRJ5fTxx/DnP0OP\nHnD77akjbjWxEJWkKjJ8OJxxBrz/Piy7bJoNrdQmBJIkqTT694cTToAOHWDoUFhxxawTzTubFUlS\nlZg6FbbYAn7zm/TnllvCQgtlnapy2KyocI7NklTZ3n8/zYBeeSVcfjkccUTWiZpnsyJJqmL/+Q/c\ndx+89FJqPnDaaVknkiRJ5fbEE7DbbrD33tCvH2y1VdaJCtMu6wCSpLl79dU06DQ1wS67wPXXZ51I\nkiSVU4ypOeEee8ADD0DfvtVfhIIzopJUsSZPToPOn/8MXbpknUaSJJVbr15w3nmw3HLw0Uew+OJZ\nJyoe94hKUgWKEfbaCzp2hIsuyjpNdXCPaOEcmyUpezNnQu/eqQlR377pDelf/jLrVG3jHlFJqhKv\nvALXXAOTJsF770FjY9aJJElSOUybBuPHw+DBcOmlaS/os8/Cyitnnaw0LEQlKWMTJ8Ktt6YlN3ff\nDaefDltvnc4Da98+63SSJKnUrroKunWDxRaD+eeHG26A3XfPOlVpWYhKUsbOPTcdSr355vDcc7D2\n2lknkiRJpRZj6orfrRt88UVairvWWlmnKh/3iEpSht5+O+0DHTsWlloq6zTVzT2ihXNslqTymDkT\nzj8fHn44vSF9+OFZJyoN94hKUoX54otUhF5xBRxzjEWoJEn14oknUhG6wALw5JO1uwe0JRaiklRm\n//oXHHYYhABLLpkOpZYkSbXts8/SzOfgwd8ezbbgglmnyo6FqCSV0TPPwP77w803V28rdkmSNG+e\negouvxyWXx7GjEnngtY794hKUpl8/HHaD3rddemMUBWXe0QL59gsScU1cSJsumnagnPAAWlJ7g9+\nkHWq8mlubG5X7jCSVG8GDoQtt0xF6J57WoRKklQPevSAXXdN23Fefx0uuqi+itCWuDRXkkpg5kx4\n6y0YORKOOgpuuw1WWy29KyplIYSwD/AzYDnghhjjExlHkqSaNG4cXH89PPpoWo67225ZJ6pMLRai\nIYRVgF7ACsBM4NYY4zUhhKWAPsDqwDjgwBjjJ/nnXAN0BqYCR8YYh5cmviRVpqOPhscfT82I+vSB\nnXbKOpHqXYyxL9A3hLAkcDlgISpJRTR9Opx4YipA99gD+veHddbJOlXlas2M6Azg9Bjj8BDCosCL\nIYRBwFHAkzHGy0IIZwPnAueEEDoDa8cY1wkhbAXcBGxdqr+AJFWa3r3h+efhv/+FhRfOOo1qVQih\nB7AXMDnGuOks1/cAriJtv+kRY+w+21P/D7i+bEElqca9+CKMGgWPPAJTp8KgQa6Aao0W94jGGCd9\nPaMZY/wMGAWsAuwD9Mzf1jP/Ofk/e+Xvfx5YIoTwwyLnlqSK9Mgj8LvfwT33WISq5O4Adp/1Qgih\nHXBd/vpGwK9CCOvP8vVLgcdcqSRJxfHpp7D77jBgAGy8MTz0kEVoa83THtEQwhpAR+A54IcxxsmQ\nitUQwvL521YG3pnlaePz1yYXGlaSKs2ZZ8Kzz6bH06bBlClpSc4WW2SbS7UvxvhsCGH12S53AsbE\nGN8CCCHcR3qDeHQI4WRgZ2DxEEKHGOMt5U0sSbVl7NjUiGjnndMb0Jo3rS5E88tyHwROiTF+FkKY\nW3/3ObXnneO9jY2N3zxuaGigoaGhtXEkKXNjx0LPntC3L7TLry/ZZBNYZJFsc9WLXC5HLpfLOkal\nmf3N4HdJxSkxxmuBa1v6Bo7NktQ6t92W9oBefXXWSSrHvIzNrTpHNIQwP9AfGBBjvDp/bRTQEGOc\nHEJYAXg6xrhBCOGm/OM++ftGAzt8PXs6y/f0rDJJVe2cc1JjgiuvzDqJoD7PEc3PiPb7eo9oCGF/\nYLcY46/znx8KbBljPKWV38+xWZJa0NQEI0bAwQfDXXdBp05ZJ6pcxThH9HZg5NdFaN6jwJH5x0cC\nfWe5fnj+B28NfDx7ESpJ1e6rr+COO+DXv846ifQd7wKrzfL5KsCEjLJIUs159NF0HNvBB6czwn/8\n46wTVa/WHN+yLXAI8HIIYRhpme15QHfg/hDC0cDbwAEAMcbHQgh7hhDeIB3fclSpwktSuX32WTqc\netw46NgR1lsv60Sqc4Hvbol5AeiQnymdCBwM/CqLYJJUSyZOhNNPhyefTA2Jtt8+60TVr8VCNMb4\nT2C+uXx5l7k856RCQklSpereHVZfHe67D35oP3BlKIRwL9AALBNCeBvoGmO8I9+UaBDfHt8yKsOY\nklTVZs6ELl3SmaAnnwxPP52646pw89Q1V5Lq1YcfwvjxcMMNMHw4rLpq1olU72KMXeZyfQAwoK3f\nt7Gx0SZFkgR88gmceCJMmgTvvANLL511ourRmqZFrWpWVAo2RJBU6d59N8183nsvvPEGLLhgalB0\n+ulZJ9Oc1GOzomJzbJak1Ijwxhvhzjths83gqqtgscWyTlWdmhubLUQlaQ7uvht+9zvYd9+0JGeH\nHWC+uW1SUEWwEC2cY7OkevfPf8Ktt6Y3oA8/HI47DoIjS5s1Nza7NFeSZjN2LJx2GuRysOmmWaeR\nJEnlcMst0K0b7LEH9OsHSy2VdaLaZiEqSXm9ekHPnuld0D/8wSJUkqR68OabMGgQdO2aZkTXXjvr\nRPXBQlRSXZsxAz79NL3zee65cNNNqRnBT36SdTJJklRKTz8Nl10GL7wA226b+kJYhJaPhaikujVj\nBuy0E4wYAcssA48/bkt2ya65kurBjBlw/PFwwglpT+gqq2SdqLbYNVeSmtGtG/zjH6kAbdcu6zQq\nlM2KCufYLKnWffEF/PGP0KcPrLMOPPWUzYhKyWZFkjSLGOH22+H66+GllyxCJUmqBzHC0UfD1Klp\nT+iaa1qEZslCVFJdmT4dDjsMRo+GwYNh5ZWzTiRJkkopRmhshCuugA03hGeegYUWyjqVnAeQVBem\nTUtNiQ4/HD77DJ5/HjbaKOtUkiSplC68EBZcEPr3h9deg+eeswitFBaikmrea6/BCiukj08+gQce\ngB/8IOtUkiSpVGJM54Lecgv897+pM+4qq8B882WdTF+zWZGkmjZtWjqK5eijU2c81S6bFRXOsVlS\ntevSBR57DJqa0lEsd91lR/ws2axIUt158cVUeH7wAay/fmrRLqllHt8iqVqNGAG5HIwZA+3bw+KL\n25AwKx7fIqkuvfoq7LxzOqR6001hgw1cilsPnBEtnGOzpGoUI9x9N9xxB+yyC5x3XtaJ9DVnRCXV\njU8+gZ//HK68Eg45JOs0kiSp1B56CC64AA4+GE48Mes0ai1nRCXVlMMOg0UXhRtvzDqJys0Z0cI5\nNkuqFu+9B337pvPA+/aF+++H7bbLOpVm19zY7KppSVXv739PjQh++MO0N/TKK7NOJEmSSqGpCY46\nCtZdF558Mh3FduutFqHVyKW5kqrSRx/BgQemPydMgJtugk6dYKml3A8qSVKtmTkT/vGP1BF31Kg0\n9i+8cNapVAgLUUlV6brrUtF50UWwzjrpsSRJqi3Tp8OUKWnv54gRaSb0wQctQmuBhaikqjN1Klx7\nbVqSu8EGWaeRaovHt0iqFB9/DFtvDRMnwq67wrBhsOCCWadSa3h8i6SaMmkS9OmTBqIpU+Dhh7NO\npEpis6LCOTZLqhRffAH77w8dOsDVV2edRm1lsyJJVa9/f+jYMRWhSy8Nl1+edSJJklQKQ4bAJpvA\nkkvCFVdknUal4oyopIo3fHhakvPXv8K222adRpXKGdHCOTZLykpTEzz/PLz5Jpx6ajqGbb/9sk6l\nQjU3NrtHVFLF+uSTtAS3Sxf4y18sQiVJqlUXXQQ9esDaa6dtODvumHUilZqFqKSKNGAAHHRQ6or3\ni1/AIYdknUiSJBXT9Omp+Hz3XbjzTnjhBVhxxaxTqVwsRCVVjC+/hLvvhg8/THtAH38cttkm61SS\nJKnYvvgCDjggdcLfYgvo188itN5YiEqqGOeckxoUbLYZPPKIRagkSbWoqSmtdFp00TTet2+fdSJl\nwUJUUkUYODAdxzJ8eOqKK0mSasvnn8P48XDPPTBhQjoP3CK0flmISiq7GOGjj779/L774Pzz4aGH\nLEKlrDU2NtLQ0EBDQ0PWUSTVgClTYOLE9EbzGWfAggumsf7hh+EHP8g6nUoll8uRy+WavcfjWySV\n3TnnwHXXwQILpM833DA1K1hvvWxzqbp5fEvhHJslFdO0abDxxukN6OWXh+7dYbvtsk6lcvL4FkkV\n4/PP4bbb4NVXYfXVs04jSZJKpUcPWHPN1HxQmp2FqKSyuv9+2Gori1BJkmrV55/Dp5/ChRdC//5Z\np1Glapd1AEn14eOPYeRIuOEG+O1vs04jSZKK7dNP4dRTYdllYd114ec/h803zzqVKpUzopLK4sAD\nYcwYWH996Nw56zSSJKmYPvkEtt46fbz9dipGpebYrEhSyX32WTqkesIEWGyxrNOoVtmsqHCOzZLa\noqkJfvELWG211IxQ+prNiiRl6umnYcstLUIlSaolDzwA11+fluQutBA8+GDWiVRNLEQlldyAAS7H\nlSSpFjQ1peNYevSACy6AG2+EJZZIe0G/PpZNag0LUUklFWMqRPv1yzqJJEkqxKBBsM8+6XzQtdaC\nv/8dOnTIOpWqlYWopKKLEYYOhYcfhsmTYcYM2GijrFNJkqS2GjsWDjssnQm6/fZZp1Et8PgWSUXT\n1AQXXZRatnfpAvPNBz/+Mdx9NwRbyEhVobGxkVwul3UMSRXkzTfTTGjXrhahap1cLkdjY2Oz99g1\nV1LRXHFFalxw3XWpALX4VDnZNbdwjs1SfZs2LW2nmT7922ujRsHVV8M558AZZzi2a97YNVdSyTQ1\nwZAhMH48XHZZerzGGlmnkiRJ8+qaa+D222HDDb+9tsQSaWxfa63scqk2OSMqqc1ihBNOSM0LVloJ\nzjwzLd2RsuCMaOEcm6X69dVXqdjs3x822yzrNKoVzohKKqrXXoObboJx49JM6LBhsPjiWaeSJElt\ndffdsMkmFqEqH5sVSZonX3wB++2XHu+0EwwcaBEqSVI1mzkzba85++ysk6ieuDRXUqvFCCeeCB9+\nCL1727BAlcWluYVzbJbqyz33wGOPwccfw/vvw3PPObaruJobm1ucEQ0h9AghTA4h/GeWa11DCO+G\nEF7Kf+wxy9fODSGMCSGMCiHsVpy/gqSs/e9/8ItfpEHqxhsdqCRJqmZNTam3w7bbpiPX+vRxbFd5\ntWaP6B3AtUCv2a7/Ocb451kvhBA2AA4ENgBWAZ4MIazj26tSdXv/fdhhB9hzz3Q8ywILZJ1IkiQV\nYuhQWGqp1HRQykKLhWiM8dkQwupz+NKc3jPZB7gvxjgDGBdCGAN0Ap4vLKakLDz8cJoBffxx+OUv\n4aKLsk4kSZKKoW9f2HvvrFOonhXSrOjEEMLwEMJtIYQl8tdWBt6Z5Z7x+WuSqsyQIfDb38Iyy6QD\nrP/0p6wTSZKkYnn0UY9cU7baenzLDUC3GGMMIfwJuBI4ljnPks51WW5jY+M3jxsaGmhoaGhjHEnF\n8sIL6UiWs86C66+HAw7IOpE0Z7lcjlwul3UMSao6//0vvPcedOqUdRLVs1Z1zc0vze0XY9y0ua+F\nEM4BYoyxe/5rA4GuMcbvLc21M59Uee69N81+duqUPv7wh6wTSa1n19zCOTZL9eGqq+CVV+C227JO\nolrX3Njc2hnRwCyznSGEFWKMk/Kf7gu8kn/8KHBPCOEvpCW5HYAhbUotqawGDIDTT4cnn4SNN846\njSRJKqYYYcqU9Pivf01jvpSlFgvREMK9QAOwTAjhbaArsGMIoSPQBIwDfgMQYxwZQrgfGAlMB07w\nrVWp8k2aBEcdlTriWoRK9a2xsdHtMlKNaGpKTQcfeAAefDCdF9quHaywAuyyS9bpVMtas32mVUtz\nS8HlP1L2nnsORoyA++6Dn/4UunXLOpHUdi7NLZxjs1Qbxo2Dv/wFHnoIllwy9Xs44ADYcMOsk6ne\nNDc2W4hKdeb112HsWHjqKejdG372M1huOWhshPbts04ntZ2FaOEcm6XqN3Vq6vOwxx5w7LGwwQZZ\nJ1I9sxCVBMCnn8Jaa8EWW8Cqq8LFF6ciVKoFFqKFc2yWqluMcOSREALceWfWaaTiNCuSVANuuQV2\n2gn69Mk6iSRJKrY77oChQ9NZ4FKlsxCV6sRXX8Gf/wz9+2edRJIkFcP48XDwwTBxYvr8ww/h2Wdh\nkUWyzSV8BIuWAAAgAElEQVS1RrusA0gqrYcfhtVXh2WXhS23hM02yzqRJEkq1DvvQEND2gs6cGD6\nGDPGhkSqHs6ISjWsWzfo1Qvuvhs22QQWWyzrRJIkqS1mzoRp09Lj8eNh993hxBM9D1TVy0JUqlG5\nHNx0EwwfDssvn3UaSZLUVlOmwDbbpK73IcB886WGg7/7XdbJpLazEJVqzC23wLBh0K8f9OhhESpJ\nUjWLEY45BrbbDl59Nes0UvG4R1SqIZddlg6w3mQTuPlm6Nw560SSJKkQV18N//1v+lOqJc6ISlXu\n449h553hrbdgiSXgmWdg5ZWzTiVJkgr1z3/CJZfAc8/BggtmnUYqLmdEpSoWIxx/PHTqBKNGwciR\nFqGSJFW7GOH++2HffeH222HNNbNOJBWfM6JSlYoRLr8cRoxIh1cvvHDWiSRJUqEmT4YTTkhvMD/6\nKGy1VdaJpNKwEJWqxAcfpOU5X7duf/ll+Pxz6N/fIlSSpFowZAjsvTccdRTcc4/LcVXbLESlKnH9\n9alb3tcNiLbYArp0gfbts80lSZIKN2QI7LVXWoq7115Zp5FKL8QYs/nBIcSsfrZUbWbMSPtD+veH\nH/0o6zRSZQohEGMMWeeoZo7NUjZeeCEVnz16WISqtjQ3NjsjKlWBxx6DVVe1CJUkqdrNmAF33w1T\np6bPv/oKuneH226zCFV9sRCVKkSMqfFQ797w5pvf/dpLL8H552eTS5IkFc/558OgQd9tQnTXXbDb\nbtllkrJgISpVgNtvhyuugC++SPs+99sPwiyLGA49FPbcM7t8kupHY2MjDQ0NNDQ0ZB1FqjkDBkCv\nXukN5uWXzzqNVDq5XI5cLtfsPe4RlTKWy6Xi84EH4Cc/+W4BKqn13CNaOMdmqXTeeQe23DKdD7r9\n9lmnkcrDPaJSBfrXv2DiRDj99DQjuu22WSeSJEmlMH06HHwwnHqqRaj0NWdEpQzccgt065beGd1+\nezjttKwTSdXPGdHCOTZLxfHoozB27LefDxkCU6ZAv37Qrl12uaRyc0ZUqgAffwznnAMffphmQ3M5\n6NAh61SSJKmYLrsMbr4Z9t7722urrw5nnWURKs3KGVGpTA45BJqa4Gc/S8tw11wz60RSbXFGtHCO\nzVJhLrooNSMaPBhWXjnrNFL2nBGVMnb77TBsGAwdCgsvnHUaSZJUTDGmLTd9+qQVTyuumHUiqfJZ\niEol9OWXcMYZ0L9/+rAIlSSp9px/Pvz1r6kI9VgWqXUsRKUSmT4dDjww7QcZMQKWXDLrRJIkqdh6\n904zof/6Fyy7bNZppOrhHlGpyJ57LnXFfeMNWGIJePhhaN8+61RS7XOPaOEcm6V5M3YsbL01DBoE\nm22WdRqp8jQ3NluISkX0wQfwox/BSSfBKqvAfvvBQgtlnUqqDxaihXNsllpv2jTYbrvUjPCUU7JO\nI1UmC1GpxF55BZ5/Hh54ADbaCK68MutEUv2xEC2cY7PUer//PYwalc4MDf7LI82RXXOlEnrxRejc\nGfbcEzbeOLVulyRJtWvgQLj3Xhg+3CJUaisLUakAY8emc0FvvRX22SfrNJIkqZhmzIBnnkkNCL82\nfTocd1wqRG1OJLWdS3OlNpoxA37609QZ97TTsk4jyaW5hXNslr71yitw1FFpvJ/9SJa994YTT8wm\nl1RN3CMqFdHIkfDII2mA+vBDGDAgHdEiKVsWooVzbJbSjGf37nD11XDxxXDssS6/ldrKPaJSgcaP\nh8GD4a230sB06KGw7rpwwgkWoZIk1Yr//AeOPDLNgL74Iqy2WtaJpNplISq1wuGHp7NAV101HVi9\nzjpZJ5IkSW116qnQs+f3r7drB5dfnpbkOgsqlZaFqNSCIUNSU6IxY1IxKkmSqtfrr8M998DLL8Mi\ni3z3awstBAsumE0uqd5YiEpzESPMnAmXXAJnnmkRKklSLbjwQjjlFFhllayTSPXNZkXSHDz3HBx2\nGLz5Jqy5JowYAQsvnHUqSc2xWVHhHJtV6157DbbbLq10WnzxrNNIta+5sdk2K9JsHn00nQnavXtq\n2T5mjEWoJEm14E9/SvtDLUKl7DkjKs1iwgTYfPN0PMs222SdRtK8cEa0cI7NqmXOhkrl5/EtUgv6\n9YNevdIZoccfbxEqSVKtufBCZ0OlSuKMqOreY4+lNu3du8Myy0DnzjC/b9FIVccZ0cI5NqtWjR4N\n228Pb7xhISqVkzOi0myammDffaFvX1hiCRg4ELbeOutUkiSpFJwNlSqPhajq0nXXwaRJ8NVX6VgW\nD62WJKk2jR4NgwbBjTdmnUTSrCxEVXf++tf0zuhzz8ECC2SdRpIklVK3bnDaac6GSpXGQlQ1LUY4\n+2x49930+YcfwuuvpyNa1l4722ySJKk4Ro2C9977/vX334cnn4Sbby5/JknNsxBVTcvlUtF5/vnp\n8/nmS82IfFdUUr0JIawJ/AFYPMZ4YNZ5pGKYOhXOPRceeADWXXfO91x5JSy2WHlzSWpZi4VoCKEH\nsBcwOca4af7aUkAfYHVgHHBgjPGT/NeuAToDU4EjY4zDSxNdatlNN8FJJ0GXLlknkaRsxRjfBI4N\nIdyfdRapGJ5+Go45JnXDHTkSlloq60SS5kW7VtxzB7D7bNfOAZ6MMa4HDAbOBQghdAbWjjGuA/wG\nuKmIWaV5Mnlyak5w2GFZJ5Gk4gsh9AghTA4h/Ge263uEEEaHEF4PIZydVT6pVD79FE44AQ4/HK69\nFu680yJUqkYtFqIxxmeBj2a7vA/QM/+4Z/7zr6/3yj/veWCJEMIPixNVap2PPkrLb3feGfbbLx3P\nIkk16HtvFIcQ2gHX5a9vBPwqhLD+bM+zT7iq1pNPwiabpK73L78MP/tZ1okktVVb94guH2OcDBBj\nnBRCWD5/fWXgnVnuG5+/NrntEaV5M2BAGqCuuQa22irrNJJUGjHGZ0MIq892uRMwJsb4FkAI4T7S\nm8SjQwhLAxcBHUMIZ8cYu5c3sdR2McLpp8NDD8Ett8Aee2SdSFKhit2saE7vssa53dzY2PjN44aG\nBhoaGoocR/VowAA48EDYaaesk0gqpVwuRy6XyzpGpZn9DeF3ScUpMcYPgeNb+gaOzapEd90FTzyR\nZkFd6SRVrnkZm0OMc60Tv70pvePab5ZmRaOAhhjj5BDCCsDTMcYNQgg35R/3yd83Gtjh69nT2b5n\nbM3PluZFUxOssAK88AKsPvs8gaSaFkIgxlhXy07nMD7vD+wWY/x1/vNDgS1jjKe08vs5NqvijB0L\nW28NTz0Fm26adRpJ86K5sbk1zYogzXTO+g0eBY7MPz4S6DvL9cPzP3Rr4OM5FaFSqbz0Eiy7rEWo\npLr1LrDaLJ+vAkzIKItUsOnT4ZBD4A9/sAiVak1rjm+5F2gAlgkhvA10BS4FHgghHA28DRwAEGN8\nLISwZwjhDdLxLUeVKrg0q+nT4Y03oHdv941Iqiuzv1H8AtAhP1M6ETgY+FUWwaRiuPBCWHJJ+N3v\nsk4iqdhatTS3JD/Y5T8qUFMT/POfcO+98OCDaaBq3x7uuMMmRVI9qrelubO+UUxqCtg1xnhH/ii1\nq0irnnrEGC+dh+/p2KyK8eyzcMABabXTiitmnUZSWzQ3Nhe7WZFUNscfD888A0cckfaErrFG1okk\nqXxijF3mcn0AMKCt37exsdEmRcrcxx+nc8BvucUiVKpGrWla5IyoqtIjj8BZZ8GwYbDYYlmnkVQJ\n6m1GtBQcm1UpDjkkdce94Yask0gqhDOiqglNTXDqqWkW9K230jEtFqGSJNWWu+9ObzQPHZp1Ekml\nZCGqivfxx/D++3DFFTBqVNoDuvTSdsaVJKnWvPkmnHZaOjN04YWzTiOplCxEVdEmToTNN4dFFoF1\n14V+/WDxxbNOJUmSim3GjLQk99xzoWPHrNNIKjX3iKpiNTVB587pEOsLLsg6jaRK5x7Rwjk2q1SG\nDElHsHz11dzvmTo1NR4cOBDatfake0kVzT2iqjqffw6nnAJTpsAf/5h1GkmqH3bNVbENGwY//3na\nYrPxxs3fu/76FqFSLbBrrqrShAmwyy6wxRZw3XWpa54ktcQZ0cI5NqvYXn4Zdt01db/dd9+s00gq\nt+bGZt9zUsWYPBlGj05F6GGHwV13WYRKklStRo+G3XeHq66yCJX0fRaiqgh9+kCHDrDbbnDQQalR\ngSRJqk5vvJHeWL70Ujj44KzTSKpELs1V5t5+G37843Qu6BZbZJ1GUrVyaW7hHJtVDOPGwQ47wP/9\nHxx3XNZpJGXJpbmqSLfdBqutBptuCmecYREqSVK1e+cd2Gkn+P3vLUIlNc+uucpE797Q2Ah9+8KK\nK8JKK2WdSJIEds1V202cCDvvDCedBCeemHUaSVmya64q0vDhqYNeLgcbbZR1Gkm1wqW5hXNsVlu9\n9x40NMChh8J552WdRlKlcGmuKsbnn0OXLqmDnkWoJEnV74MPUmOiAw6wCJXUei7NVck1NcE118Af\n/5gK0cMOg0MOyTqVJEmak5Ej4bTTYNq01t3/5pupM25jY0ljSaoxFqIqmaFD0xKdTz+F1VeHl16C\nNdaA+f2tkySpIk2dCvvvD0ccAZ06te45Cy0EW20FwYXxkuaBe0RVMnvtBdtvD/vtlwrQ+ebLOpGk\nWuYe0cI5NuvII9Ofd96ZZQpJtaK5sdm5KZXEiBFpBvTBB2HBBbNOI0mSWnLnnTBkCLzwQtZJJNUD\nC1EV1XPPQf/+MHgwnHqqRagkSdXg1VfhrLNSR/tFFsk6jaR6YNdcFUWMqUnBL34B7drBvvt6hpgk\nVaPGxsYWz35TbZk6FQ48EC67zI72koojl8vR2EIHM/eIqihuvRWuuw4efxxWWCHrNJLqkXtEC+fY\nXJ+OOip1uL/zThsOSSou94iqJGKEN96A8ePTuWHPPGMRKklSNenZM22reeEFi1BJ5WUhqjb74x/h\nlltgueXgiitggw2yTiRJklpr5Eg480x4+mlYdNGs00iqNxaimifvvJOW7rz1Fvzzn6m5wXLLZZ1K\nkiTNi88/T/tCu3eHjTfOOo2keuQeUbXa9Omw3Xaw3nqw9tpw3HGw0kpZp5KkxD2ihXNsrh/HHAPT\npkGvXi7JlVQ67hFVUVxwASy9dNpP4qAlSVJ16tUrrWoaOtTxXFJ2LEQ1R1OnwoQJ6fHMmaml+zPP\nwLPPOmhJklStRo2CM85I5327L1RSlixENUedO8Pbb0P79unznXaCYcNgscWyzSVJKq3GxkYaGhpo\naGjIOoqK7Ot9oZdcAptsknUaSbUsl8u1eCa1e0T1PSNGwF57wZtvwvy+VSGpSrhHtHCOzbXt2GPh\nyy/hrrtc3SSpPNwjqnly882pEZFFqCRJteHuu9P2GveFSqoUlhr6xn//m45lue8+ePnlrNNIkqRi\nGD0aTjsNnnrKfaGSKoeFqAAYPx623BI23BBOPhlWXjnrRJIkqVCffw4HHAAXXwybbpp1Gkn6lntE\nBcARR6Ti8+KLs04iSW3jHtHCOTbXlg8+gEMPTUev3X23S3IllZ97RDVHb7wBAwemgeqJJ+C117JO\nJEmSiuGf/4Rf/Sp1yb34YotQSZWnXdYBVF7TpsG118JWW8G228Lw4TBlCtx7r0ezSJJU7Zqa4NJL\nYd994YYb4IorYIEFsk4lSd/njGid+b//g3//G7p1g513tjOuJEm14n//g8MPT28wDx0Kq66adSJJ\nmjtnROtAjDBxIvTrB/fcA488ArvvbhEqSVKteOYZ2Hxz6NgRcjmLUEmVz1KkxjU1wZFHpiJ0scWg\nZ09YdtmsU0mSpGKYORMuuQSuvx7uuAP22CPrRJLUOhaiNWrUKHjyybQMd/z49LHwwlmnkiRVusbG\nRhoaGmhoaMg6iloweXLqijttWlqK69FrkipFLpcjl8s1e4/Ht9Sgjz5KS3N22QWWWw7OOw8WXzzr\nVJJUWh7fUjjH5uoxeDAcdhgcfTR07ep2G0mVqbmx2UK0xsSY2rUvvzxcc03WaSSpfCxEC+fYXPlm\nzoQLL4RbbknbbXbdNetEkjR3niNaJ95/H447Li3DveOOrNNIkqRimjgRDjkkPX7xRVhxxWzzSFIh\n7JpbIyZMSGeDrr02/OMfsNBCWSeSJEnF8sQTsMUWsMMO6bFFqKRq54xolXvsMXj77bQM97jj4Jxz\nsk4kSZKKZcYMaGxMK53uuQd23DHrRJJUHO4RrWKPP56aFPz85/CjH8Hxx2edSJKy4x7RwtXK2Nyr\nF9x5Z9YpimPSJFhlFbj77tT/QZKqScn2iIYQxgGfAE3A9BhjpxDCUkAfYHVgHHBgjPGTQn6OvuvN\nN9N+0KOPTgOT745KkvStf/0LNt0U9t476ySFW2AB+MlPoJ2bqSTVmEKX5jYBDTHGj2a5dg7wZIzx\nshDC2cC5+WsqgltuSctvV1oJTj7ZIlSSpDlZf33YaaesU0iS5qbQQjTw/YZH+wA75B/3BHJYiBZF\nnz7QrRsMGQIdOmSdRpKkylQDq4slqeYVutAjAo+HEF4IIRybv/bDGONkgBjjJGC5An+GgDFj4KST\n4G9/swiVJKklwd3CklTRCp0R/UmMcVIIYTlgUAjhNVJxqiIZOTIdzXLeeXD++akpkSRJmjtnRCWp\n8hVUiOZnPIkx/i+E8FegEzA5hPDDGOPkEMIKwHtze35jY+M3jxsaGmhoaCgkTs2YPBk++ii1au/Z\nEzbeGLbZJs2ISpKSXC5HLpfLOoYkSWqDNh/fEkJYGGgXY/wshLAIMAi4ANgZ+DDG2D3frGipGOP3\n9ojWSov4Ynv7bdhkE1hhBejYEa691nbtktQaHt9SuFoZm3/9a/jxj9OfkqTslOr4lh8Cj4QQYv77\n3BNjHBRCGArcH0I4GngbOKCAn1F3rrwyDZyXX551EklSPWpsbKz6VUo1UEtLUlVrzaqlNs+IFqpW\n3nUtpv/9D9ZdF159NR3PIklqPWdEC1crY/Nxx0GnTulPSVJ2mhubPR65AvTtC1ttlQbNgw6yCJUk\nqRA1UEtLUs0rtGuuCnTWWfDww3DNNbDiiqkxkSRJkiTVMgvRDD30EPz1r/DSS7DEElmnkSSpdniO\nqCRVNgvRMosR7r03nQ16xRXw6KMWoZIkFZNLcyWp8rlHtMzOPx8uvTSdFXr99WlvqCRJKi5nRCWp\nsjkjWgYTJsDhh8NHH8Hnn8Mzz8Byy2WdSpKk2uSMqCRVPgvREmtqgiOPhI4dYf/9YYMNXIorSZIk\nqb5ZiJZQjNCtG3z2WVqOO7+vtiRJZeHSXEmqbJZGRTRpEvTp8+3nAwfC+++n7rgWoZIklYdLcyWp\n8lkeFdG558LEibDeeunzXXeFk0+G9u2zzSVJUr1xRlSSKpuFaJF89BE88giMGWMjIkmSsuSMqCRV\nPo9vKZJevWDPPS1CJUmSJKklzogW6JlnYMAA6N07FaOSJCl7Ls2VpMrmjGiBunZNy3L/8Af46U+z\nTiNJklyaK0mVzxnRAkyZAkOHQv/+sMgiWaeRJElfc0ZUkiqbM6IFGDwYtt7aIlSSpErijKgkVT4L\n0QIMGACdO2edQpIkSZKqi4VoG8VoISpJUqVyaa4kVTYL0VaKEUaMgLPPhrXWgsUXhwUWgPXXzzqZ\nJEnF09jYSC6XyzpGQVyaK0nZyuVyNDY2NntPiBn9ax1CiFn97Hn16aewyy4weTL86lfpY401YMEF\nUzEqScpeCIEYo/NgBaimsbk5hx0Gu+2W/pQkZae5sdmuua1wyimw0Ubw739DO+eQJUmqaDVQS0tS\nzbMQnYsPPoALL4T33oMXXoBhwyxCJUmSJKkYLK3mYMqU1ITo009hhx1g4EBYdNGsU0mSpNayWZEk\nVTZnRGfRty8cdxx8/jkccQRcd50DmSRJ1caluZJU+SxE88aPh1//Gvr0gR/9CJZeOutEkiSprXwj\nWZIqm4Uo8L//wUEHwUknwY47Zp1GkiQVwhlRSap8db9H9Jln0gzodtvBuedmnUaSJEmSal9dz4g+\n9xzstx/cc086b0ySJNUGl+ZKUmWry0L0xBPh4Ydh6lTo3dsiVJKkWuLSXEmqfHVXiN5zDwweDM8/\nD4svDksumXUiSZJUbM6ISlJlq4tCtKkJzj8fRo+Gv/8dBg2C1VbLOpUkSSoFZ0QlqfLVfLOiGNNS\n3H/8Aw4+GAYMgM02yzqVJEmSJNWvmp8RvfxyGDoUnnoqLcWVJEm1z6W5klTZaroQffFFuOKKVIha\nhEqSVB9cmitJla/mCtGvvoILLkjng44ZA9dc435QSZLqjTOiklTZaqYQ7dEjLb8dMQLWXRcuvjjN\ngnbsmHUySZJUTs6ISlLlq4lCdNIkOPNMuOoqOOKIdC6o74RKkiRJUmWqiUL0qqugS5dUhEqSJPmG\ntCRVtqouRJ9/HiZOhFtvTY2JJEmSXJorSZWvKgvRzz6DU05Je0I32QTOOw/WWCPrVJIkqVI4IypJ\nla3qCtEY0zLcRReFl1+GxRbLOpEkSaokzohKUuWrukL05pth/Hj4979hgQWyTiNJkiRJmldVUYh+\n+SXsvz/kctC+vUWoJElqnktzJamyVXQhOno0vPUWXH89LLIITJgAP/hB+pAkSZoTl+ZKUuWr2EL0\n9ddhu+1giy2gQwf4y1+cBZUkSa3jjKgkVbaKLESnT4dDDoFu3eCEE7JOI0mSqokzopJU+dplHWB2\nEyfCz38OK60Exx+fdRpJkmpDCGHhEMKdIYSbQwhdss4jSapvJStEQwh7hBBGhxBeDyGcPbf73ngD\nVl0Vll46fXToAFttBQ8+6LKaucnlcllHqGq+fm3na9d2vnaF8fUrin2BB2KMvwH2zjpMqfnfELXJ\nfwtUyfz9nDclKURDCO2A64DdgY2AX4UQ1p/TvTfeCAcckArSN96AyZPhggtSd1zNmb/khfH1aztf\nu7bztSuMr9/3hRB6hBAmhxD+M9v1ub0RvArwTv7xzLIFzYBLc2uX/xaokvn7OW9KNSPaCRgTY3wr\nxjgduA/YZ/abvvwSevWCk076dkZ00UVLlEiSpNpyB+kN32+08EbwO6RiFKDm5wtffTWXyc8txX+I\nFvo92/L8eX1Oa+4v1j21IKu/Z638fs7r81p7b0v31cvvJ5Tn71qqQnRlvn3XFeDd/LXv6NMHNt8c\n1lqrRCkkSapRMcZngY9mu9zcG8GPAPuHEK4H+pUvaTZeeSWXyc+tlf/QtxAtLQvRwp9vIVpa5fi7\nhliC9SshhP2B3WKMv85/fiiwZYzxlFnuceGMJKmoYow1P9M3qxDC6kC/GOOm+c/3A3afbfztFGP8\nXSu/n2OzJKmo5jY2l+r4lneB1Wb5fBVgQmsCSZKkNpvT2Nrq4tKxWZJULqVamvsC0CGEsHoIYQHg\nYODREv0sSZKUtPhGsCRJlaAkhWiMcSZwEjAIeBW4L8Y4qhQ/S5KkOhb47iyobwRLkqpCSfaISpKk\n0goh3As0AMsAk4GuMcY7QgidgatIbzb3iDFeml1KSZLmrFRLc5vVzBlnmoMQwrgQwogQwrAQwpD8\ntaVCCINCCK+FEB4PISyRdc5KMKdz9Zp7rUII14QQxoQQhocQOmaTunLM5fXrGkJ4N4TwUv5jj1m+\ndm7+9RsVQtgtm9SVIYSwSghhcAhhZAjh5RDC7/LX/f1rwRxeu5Pz1/3da0aMsUuMcaUY4w9ijKvF\nGO/IXx8QY1wvxriORagkqVKVvRBt4YwzzVkT0BBj3CzG2Cl/7RzgyRjjesBg4NzM0lWW752rx1xe\nq/yswdoxxnWA3wA3lTNohZrT6wfw5xjj5vmPgQAhhA2AA4ENgM7ADSGEem50MgM4Pca4IbANcGL+\n3zZ//1o2+2t30izjgr97GQshLBxCuDOEcHMIoUvWeaRZhRDWDCHcFkK4P+ss0pyEEPYJIdwSQngk\nhLBr1nkqSRYzos2dcaY5C3z/f6t9gJ75xz2BX5Q1UYWay7l6s79W+8xyvdf/t3c3oXGVURzGn4PF\njQVBsBFUUBDdZqEgigtRXHShUBREQdsiiv3AvQgu2y5cSKmCii5EBCvUVCjavWJVUKimC4WWtEJr\nobhQNxqPi3vHGSf3Tpt08t4b5vmtJjeT5HDynzBv7vtRf90J4PqImCtRZ1+19A+ad+J8jGr999+Z\neQb4ier1PZMy83xmfl8//h04RbVRjPm7jJbeDc6eNnvd2wYczswXgEe7LkYalZmnM/O5ruuQ2mTm\nQn2k1g6qf6Kq1sVA9Gbg7MjH5xi+4VCzBD6PiG8iYvDHdi4zL0D1Jg64sbPq+m/LWK+21NfHs/gL\nZrHN7nr66DsjU0vtX4uIuA2YB75i5WvV/E0w0rsT9SWzN2VNU/Dr623LZm5h2O/lYoVqJq0hn1JR\nV5HRV4BDZarcGLoYiF7VGWcz6r7MvBvYSvWm7AHs2TSYxSvzBtUU0nngPPBafd3+NYiIzcDHwEv1\n3b22nti/MQ29M3vrY8UU/MssmzlLNRiF5t5L07TafP73tDLlSavPaETsB44NZv+o0sVA1DPOVqm+\ni0JmXgQ+oZqCdmEwjS8ibgJ+7a7C3mvr1Tng1pHnmcUGmXkxh9trv81wCqT9GxMRm6gGUu9n5kJ9\n2fxdgabemb310TIFf9KymSPA4xFxCPi0XKWaRavNZ0TcEBFvAvPeKVUJa8joXuAhqr+jzxcttue6\nGIh6xtkq1JtEbK4fXwc8Apyk6tn2+mnPAguN32A2jZ+rN9qr7Qx7dRR4BiAi7gV+G0yhnHH/6189\neBrYBvxQPz4KPBkR10bE7cAdwNfFquynd4HFzHx95Jr5uzIremf2impdNpOZf2bmzszcnZkfdlKd\nZt2kfF7KzBfrXaIPdFKdNDmjBzPznszclZlvdVJdT20q/QMzczki9gDHGZ5xdqp0HRvIHHAkIpLq\n9/VBZh6PiG+BjyJiJ7AEPNFlkX0RI+fqRcQS8CqwHzg83qvMPBYRWyPiZ+APqkXkM62lfw/WR4v8\nA9jOFh4AAAEnSURBVJyh2uGVzFysdylcBP4Cdo3cvZo5EXE/8DRwMiK+o5oq+jJwgIbXqvkbmtC7\np8xeMU53Vp+ZT/WdGV2D4gNRgHoL/ru6+NkbTWaeptq4Y/z6JeDh8hX1W2a2HS3Q2KvM3LOO5Ww4\nLf17b8Lz9wH71q+ijSMzvwCuafm0+ZtgQu8+m/A1Zm+6XDajPjOf6jszugZdTM2VJEndGl/C4LIZ\n9Yn5VN+Z0SlwICpJ0gypp+B/CdwZEUsRsSMzl4G9VMtmfqQ6p9VlMyrOfKrvzOj0hMtqJEmSJEkl\neUdUkiRJklSUA1FJkiRJUlEORCVJkiRJRTkQlSRJkiQV5UBUkiRJklSUA1FJkiRJUlEORCVJkiRJ\nRTkQlSRJkiQV5UBUkiRJklTUv2fCWd3jCpNQAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x72df4cd3de80>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def improved_bitslide2(nbits, offx_lsb, cutoff):\n",
+ " bs = lambda x: min(bitslide(cutoff, offx_lsb), key=lambda y: abs(x-y))\n",
+ " return [ sum((2**n + offx_lsb) if i&(2**n) else 0 for n in range(cutoff, nbits))\n",
+ " + bs(i%(2**cutoff)) for i in range(2**nbits) ]\n",
+ "\n",
+ "plot_bitslide(improved_bitslide2(8, 2.5, 5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Channel 23 offset: 0.741lsb\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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\nrkJggg==\n",
+ "text/plain": [
+ "<matplotlib.figure.Figure at 0x72df4c700198>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_run('Linearity test run', *fetch_runs('test102'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,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\" width=\"800\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "def simulate_bitslide(data):\n",
+ " nbits = len(data)\n",
+ " return [ sum(data[n] if i&(2**n) else 0 for n in range(nbits)) for i in range(2**nbits) ]\n",
+ "\n",
+ "info, data, (zero_cal, _stdev) = fetch_run(['test103'])\n",
+ "data = np.array(next(iter(data.values())))[:,1] - zero_cal\n",
+ "plot_bitslide(simulate_bitslide(data))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/* Put everything inside the global mpl namespace */\n",
+ "window.mpl = {};\n",
+ "\n",
+ "\n",
+ "mpl.get_websocket_type = function() {\n",
+ " if (typeof(WebSocket) !== 'undefined') {\n",
+ " return WebSocket;\n",
+ " } else if (typeof(MozWebSocket) !== 'undefined') {\n",
+ " return MozWebSocket;\n",
+ " } else {\n",
+ " alert('Your browser does not have WebSocket support.' +\n",
+ " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
+ " 'Firefox 4 and 5 are also supported but you ' +\n",
+ " 'have to enable WebSockets in about:config.');\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
+ " this.id = figure_id;\n",
+ "\n",
+ " this.ws = websocket;\n",
+ "\n",
+ " this.supports_binary = (this.ws.binaryType != undefined);\n",
+ "\n",
+ " if (!this.supports_binary) {\n",
+ " var warnings = document.getElementById(\"mpl-warnings\");\n",
+ " if (warnings) {\n",
+ " warnings.style.display = 'block';\n",
+ " warnings.textContent = (\n",
+ " \"This browser does not support binary websocket messages. \" +\n",
+ " \"Performance may be slow.\");\n",
+ " }\n",
+ " }\n",
+ "\n",
+ " this.imageObj = new Image();\n",
+ "\n",
+ " this.context = undefined;\n",
+ " this.message = undefined;\n",
+ " this.canvas = undefined;\n",
+ " this.rubberband_canvas = undefined;\n",
+ " this.rubberband_context = undefined;\n",
+ " this.format_dropdown = undefined;\n",
+ "\n",
+ " this.image_mode = 'full';\n",
+ "\n",
+ " this.root = $('<div/>');\n",
+ " this._root_extra_style(this.root)\n",
+ " this.root.attr('style', 'display: inline-block');\n",
+ "\n",
+ " $(parent_element).append(this.root);\n",
+ "\n",
+ " this._init_header(this);\n",
+ " this._init_canvas(this);\n",
+ " this._init_toolbar(this);\n",
+ "\n",
+ " var fig = this;\n",
+ "\n",
+ " this.waiting = false;\n",
+ "\n",
+ " this.ws.onopen = function () {\n",
+ " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
+ " fig.send_message(\"send_image_mode\", {});\n",
+ " if (mpl.ratio != 1) {\n",
+ " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
+ " }\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " }\n",
+ "\n",
+ " this.imageObj.onload = function() {\n",
+ " if (fig.image_mode == 'full') {\n",
+ " // Full images could contain transparency (where diff images\n",
+ " // almost always do), so we need to clear the canvas so that\n",
+ " // there is no ghosting.\n",
+ " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
+ " }\n",
+ " fig.context.drawImage(fig.imageObj, 0, 0);\n",
+ " };\n",
+ "\n",
+ " this.imageObj.onunload = function() {\n",
+ " this.ws.close();\n",
+ " }\n",
+ "\n",
+ " this.ws.onmessage = this._make_on_message_function(this);\n",
+ "\n",
+ " this.ondownload = ondownload;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_header = function() {\n",
+ " var titlebar = $(\n",
+ " '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
+ " 'ui-helper-clearfix\"/>');\n",
+ " var titletext = $(\n",
+ " '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
+ " 'text-align: center; padding: 3px;\"/>');\n",
+ " titlebar.append(titletext)\n",
+ " this.root.append(titlebar);\n",
+ " this.header = titletext[0];\n",
+ "}\n",
+ "\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_canvas = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var canvas_div = $('<div/>');\n",
+ "\n",
+ " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
+ "\n",
+ " function canvas_keyboard_event(event) {\n",
+ " return fig.key_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " canvas_div.keydown('key_press', canvas_keyboard_event);\n",
+ " canvas_div.keyup('key_release', canvas_keyboard_event);\n",
+ " this.canvas_div = canvas_div\n",
+ " this._canvas_extra_style(canvas_div)\n",
+ " this.root.append(canvas_div);\n",
+ "\n",
+ " var canvas = $('<canvas/>');\n",
+ " canvas.addClass('mpl-canvas');\n",
+ " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
+ "\n",
+ " this.canvas = canvas[0];\n",
+ " this.context = canvas[0].getContext(\"2d\");\n",
+ "\n",
+ " var backingStore = this.context.backingStorePixelRatio ||\n",
+ "\tthis.context.webkitBackingStorePixelRatio ||\n",
+ "\tthis.context.mozBackingStorePixelRatio ||\n",
+ "\tthis.context.msBackingStorePixelRatio ||\n",
+ "\tthis.context.oBackingStorePixelRatio ||\n",
+ "\tthis.context.backingStorePixelRatio || 1;\n",
+ "\n",
+ " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
+ "\n",
+ " var rubberband = $('<canvas/>');\n",
+ " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
+ "\n",
+ " var pass_mouse_events = true;\n",
+ "\n",
+ " canvas_div.resizable({\n",
+ " start: function(event, ui) {\n",
+ " pass_mouse_events = false;\n",
+ " },\n",
+ " resize: function(event, ui) {\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " stop: function(event, ui) {\n",
+ " pass_mouse_events = true;\n",
+ " fig.request_resize(ui.size.width, ui.size.height);\n",
+ " },\n",
+ " });\n",
+ "\n",
+ " function mouse_event_fn(event) {\n",
+ " if (pass_mouse_events)\n",
+ " return fig.mouse_event(event, event['data']);\n",
+ " }\n",
+ "\n",
+ " rubberband.mousedown('button_press', mouse_event_fn);\n",
+ " rubberband.mouseup('button_release', mouse_event_fn);\n",
+ " // Throttle sequential mouse events to 1 every 20ms.\n",
+ " rubberband.mousemove('motion_notify', mouse_event_fn);\n",
+ "\n",
+ " rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
+ " rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
+ "\n",
+ " canvas_div.on(\"wheel\", function (event) {\n",
+ " event = event.originalEvent;\n",
+ " event['data'] = 'scroll'\n",
+ " if (event.deltaY < 0) {\n",
+ " event.step = 1;\n",
+ " } else {\n",
+ " event.step = -1;\n",
+ " }\n",
+ " mouse_event_fn(event);\n",
+ " });\n",
+ "\n",
+ " canvas_div.append(canvas);\n",
+ " canvas_div.append(rubberband);\n",
+ "\n",
+ " this.rubberband = rubberband;\n",
+ " this.rubberband_canvas = rubberband[0];\n",
+ " this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
+ " this.rubberband_context.strokeStyle = \"#000000\";\n",
+ "\n",
+ " this._resize_canvas = function(width, height) {\n",
+ " // Keep the size of the canvas, canvas container, and rubber band\n",
+ " // canvas in synch.\n",
+ " canvas_div.css('width', width)\n",
+ " canvas_div.css('height', height)\n",
+ "\n",
+ " canvas.attr('width', width * mpl.ratio);\n",
+ " canvas.attr('height', height * mpl.ratio);\n",
+ " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
+ "\n",
+ " rubberband.attr('width', width);\n",
+ " rubberband.attr('height', height);\n",
+ " }\n",
+ "\n",
+ " // Set the figure to an initial 600x600px, this will subsequently be updated\n",
+ " // upon first draw.\n",
+ " this._resize_canvas(600, 600);\n",
+ "\n",
+ " // Disable right mouse context menu.\n",
+ " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
+ " return false;\n",
+ " });\n",
+ "\n",
+ " function set_focus () {\n",
+ " canvas.focus();\n",
+ " canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " window.setTimeout(set_focus, 100);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items) {\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) {\n",
+ " // put a spacer in here.\n",
+ " continue;\n",
+ " }\n",
+ " var button = $('<button/>');\n",
+ " button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
+ " 'ui-button-icon-only');\n",
+ " button.attr('role', 'button');\n",
+ " button.attr('aria-disabled', 'false');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ "\n",
+ " var icon_img = $('<span/>');\n",
+ " icon_img.addClass('ui-button-icon-primary ui-icon');\n",
+ " icon_img.addClass(image);\n",
+ " icon_img.addClass('ui-corner-all');\n",
+ "\n",
+ " var tooltip_span = $('<span/>');\n",
+ " tooltip_span.addClass('ui-button-text');\n",
+ " tooltip_span.html(tooltip);\n",
+ "\n",
+ " button.append(icon_img);\n",
+ " button.append(tooltip_span);\n",
+ "\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " var fmt_picker_span = $('<span/>');\n",
+ "\n",
+ " var fmt_picker = $('<select/>');\n",
+ " fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
+ " fmt_picker_span.append(fmt_picker);\n",
+ " nav_element.append(fmt_picker_span);\n",
+ " this.format_dropdown = fmt_picker[0];\n",
+ "\n",
+ " for (var ind in mpl.extensions) {\n",
+ " var fmt = mpl.extensions[ind];\n",
+ " var option = $(\n",
+ " '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
+ " fmt_picker.append(option)\n",
+ " }\n",
+ "\n",
+ " // Add hover states to the ui-buttons\n",
+ " $( \".ui-button\" ).hover(\n",
+ " function() { $(this).addClass(\"ui-state-hover\");},\n",
+ " function() { $(this).removeClass(\"ui-state-hover\");}\n",
+ " );\n",
+ "\n",
+ " var status_bar = $('<span class=\"mpl-message\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
+ " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
+ " // which will in turn request a refresh of the image.\n",
+ " this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_message = function(type, properties) {\n",
+ " properties['type'] = type;\n",
+ " properties['figure_id'] = this.id;\n",
+ " this.ws.send(JSON.stringify(properties));\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.send_draw_message = function() {\n",
+ " if (!this.waiting) {\n",
+ " this.waiting = true;\n",
+ " this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " var format_dropdown = fig.format_dropdown;\n",
+ " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
+ " fig.ondownload(fig, format);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
+ " var size = msg['size'];\n",
+ " if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
+ " fig._resize_canvas(size[0], size[1]);\n",
+ " fig.send_message(\"refresh\", {});\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
+ " var x0 = msg['x0'] / mpl.ratio;\n",
+ " var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
+ " var x1 = msg['x1'] / mpl.ratio;\n",
+ " var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
+ " x0 = Math.floor(x0) + 0.5;\n",
+ " y0 = Math.floor(y0) + 0.5;\n",
+ " x1 = Math.floor(x1) + 0.5;\n",
+ " y1 = Math.floor(y1) + 0.5;\n",
+ " var min_x = Math.min(x0, x1);\n",
+ " var min_y = Math.min(y0, y1);\n",
+ " var width = Math.abs(x1 - x0);\n",
+ " var height = Math.abs(y1 - y0);\n",
+ "\n",
+ " fig.rubberband_context.clearRect(\n",
+ " 0, 0, fig.canvas.width, fig.canvas.height);\n",
+ "\n",
+ " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
+ " // Updates the figure title.\n",
+ " fig.header.textContent = msg['label'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
+ " var cursor = msg['cursor'];\n",
+ " switch(cursor)\n",
+ " {\n",
+ " case 0:\n",
+ " cursor = 'pointer';\n",
+ " break;\n",
+ " case 1:\n",
+ " cursor = 'default';\n",
+ " break;\n",
+ " case 2:\n",
+ " cursor = 'crosshair';\n",
+ " break;\n",
+ " case 3:\n",
+ " cursor = 'move';\n",
+ " break;\n",
+ " }\n",
+ " fig.rubberband_canvas.style.cursor = cursor;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
+ " fig.message.textContent = msg['message'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
+ " // Request the server to send over a new figure.\n",
+ " fig.send_draw_message();\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
+ " fig.image_mode = msg['mode'];\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Called whenever the canvas gets updated.\n",
+ " this.send_message(\"ack\", {});\n",
+ "}\n",
+ "\n",
+ "// A function to construct a web socket function for onmessage handling.\n",
+ "// Called in the figure constructor.\n",
+ "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
+ " return function socket_on_message(evt) {\n",
+ " if (evt.data instanceof Blob) {\n",
+ " /* FIXME: We get \"Resource interpreted as Image but\n",
+ " * transferred with MIME type text/plain:\" errors on\n",
+ " * Chrome. But how to set the MIME type? It doesn't seem\n",
+ " * to be part of the websocket stream */\n",
+ " evt.data.type = \"image/png\";\n",
+ "\n",
+ " /* Free the memory for the previous frames */\n",
+ " if (fig.imageObj.src) {\n",
+ " (window.URL || window.webkitURL).revokeObjectURL(\n",
+ " fig.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
+ " evt.data);\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ " else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
+ " fig.imageObj.src = evt.data;\n",
+ " fig.updated_canvas_event();\n",
+ " fig.waiting = false;\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var msg = JSON.parse(evt.data);\n",
+ " var msg_type = msg['type'];\n",
+ "\n",
+ " // Call the \"handle_{type}\" callback, which takes\n",
+ " // the figure and JSON message as its only arguments.\n",
+ " try {\n",
+ " var callback = fig[\"handle_\" + msg_type];\n",
+ " } catch (e) {\n",
+ " console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " if (callback) {\n",
+ " try {\n",
+ " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
+ " callback(fig, msg);\n",
+ " } catch (e) {\n",
+ " console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
+ " }\n",
+ " }\n",
+ " };\n",
+ "}\n",
+ "\n",
+ "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
+ "mpl.findpos = function(e) {\n",
+ " //this section is from http://www.quirksmode.org/js/events_properties.html\n",
+ " var targ;\n",
+ " if (!e)\n",
+ " e = window.event;\n",
+ " if (e.target)\n",
+ " targ = e.target;\n",
+ " else if (e.srcElement)\n",
+ " targ = e.srcElement;\n",
+ " if (targ.nodeType == 3) // defeat Safari bug\n",
+ " targ = targ.parentNode;\n",
+ "\n",
+ " // jQuery normalizes the pageX and pageY\n",
+ " // pageX,Y are the mouse positions relative to the document\n",
+ " // offset() returns the position of the element relative to the document\n",
+ " var x = e.pageX - $(targ).offset().left;\n",
+ " var y = e.pageY - $(targ).offset().top;\n",
+ "\n",
+ " return {\"x\": x, \"y\": y};\n",
+ "};\n",
+ "\n",
+ "/*\n",
+ " * return a copy of an object with only non-object keys\n",
+ " * we need this to avoid circular references\n",
+ " * http://stackoverflow.com/a/24161582/3208463\n",
+ " */\n",
+ "function simpleKeys (original) {\n",
+ " return Object.keys(original).reduce(function (obj, key) {\n",
+ " if (typeof original[key] !== 'object')\n",
+ " obj[key] = original[key]\n",
+ " return obj;\n",
+ " }, {});\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.mouse_event = function(event, name) {\n",
+ " var canvas_pos = mpl.findpos(event)\n",
+ "\n",
+ " if (name === 'button_press')\n",
+ " {\n",
+ " this.canvas.focus();\n",
+ " this.canvas_div.focus();\n",
+ " }\n",
+ "\n",
+ " var x = canvas_pos.x * mpl.ratio;\n",
+ " var y = canvas_pos.y * mpl.ratio;\n",
+ "\n",
+ " this.send_message(name, {x: x, y: y, button: event.button,\n",
+ " step: event.step,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ "\n",
+ " /* This prevents the web browser from automatically changing to\n",
+ " * the text insertion cursor when the button is pressed. We want\n",
+ " * to control all of the cursor setting manually through the\n",
+ " * 'cursor' event from matplotlib */\n",
+ " event.preventDefault();\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " // Handle any extra behaviour associated with a key event\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.key_event = function(event, name) {\n",
+ "\n",
+ " // Prevent repeat events\n",
+ " if (name == 'key_press')\n",
+ " {\n",
+ " if (event.which === this._key)\n",
+ " return;\n",
+ " else\n",
+ " this._key = event.which;\n",
+ " }\n",
+ " if (name == 'key_release')\n",
+ " this._key = null;\n",
+ "\n",
+ " var value = '';\n",
+ " if (event.ctrlKey && event.which != 17)\n",
+ " value += \"ctrl+\";\n",
+ " if (event.altKey && event.which != 18)\n",
+ " value += \"alt+\";\n",
+ " if (event.shiftKey && event.which != 16)\n",
+ " value += \"shift+\";\n",
+ "\n",
+ " value += 'k';\n",
+ " value += event.which.toString();\n",
+ "\n",
+ " this._key_event_extra(event, name);\n",
+ "\n",
+ " this.send_message(name, {key: value,\n",
+ " guiEvent: simpleKeys(event)});\n",
+ " return false;\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
+ " if (name == 'download') {\n",
+ " this.handle_save(this, null);\n",
+ " } else {\n",
+ " this.send_message(\"toolbar_button\", {name: name});\n",
+ " }\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
+ " this.message.textContent = tooltip;\n",
+ "};\n",
+ "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",
+ "\n",
+ "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
+ "\n",
+ "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
+ " // Create a \"websocket\"-like object which calls the given IPython comm\n",
+ " // object with the appropriate methods. Currently this is a non binary\n",
+ " // socket, so there is still some room for performance tuning.\n",
+ " var ws = {};\n",
+ "\n",
+ " ws.close = function() {\n",
+ " comm.close()\n",
+ " };\n",
+ " ws.send = function(m) {\n",
+ " //console.log('sending', m);\n",
+ " comm.send(m);\n",
+ " };\n",
+ " // Register the callback with on_msg.\n",
+ " comm.on_msg(function(msg) {\n",
+ " //console.log('receiving', msg['content']['data'], msg);\n",
+ " // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
+ " ws.onmessage(msg['content']['data'])\n",
+ " });\n",
+ " return ws;\n",
+ "}\n",
+ "\n",
+ "mpl.mpl_figure_comm = function(comm, msg) {\n",
+ " // This is the function which gets called when the mpl process\n",
+ " // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
+ "\n",
+ " var id = msg.content.data.id;\n",
+ " // Get hold of the div created by the display call when the Comm\n",
+ " // socket was opened in Python.\n",
+ " var element = $(\"#\" + id);\n",
+ " var ws_proxy = comm_websocket_adapter(comm)\n",
+ "\n",
+ " function ondownload(figure, format) {\n",
+ " window.open(figure.imageObj.src);\n",
+ " }\n",
+ "\n",
+ " var fig = new mpl.figure(id, ws_proxy,\n",
+ " ondownload,\n",
+ " element.get(0));\n",
+ "\n",
+ " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
+ " // web socket which is closed, not our websocket->open comm proxy.\n",
+ " ws_proxy.onopen();\n",
+ "\n",
+ " fig.parent_element = element.get(0);\n",
+ " fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
+ " if (!fig.cell_info) {\n",
+ " console.error(\"Failed to find cell for figure\", id, fig);\n",
+ " return;\n",
+ " }\n",
+ "\n",
+ " var output_index = fig.cell_info[2]\n",
+ " var cell = fig.cell_info[0];\n",
+ "\n",
+ "};\n",
+ "\n",
+ "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
+ " var width = fig.canvas.width/mpl.ratio\n",
+ " fig.root.unbind('remove')\n",
+ "\n",
+ " // Update the output cell to use the data from the current canvas.\n",
+ " fig.push_to_output();\n",
+ " var dataURL = fig.canvas.toDataURL();\n",
+ " // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
+ " // the notebook keyboard shortcuts fail.\n",
+ " IPython.keyboard_manager.enable()\n",
+ " $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
+ " fig.close_ws(fig, msg);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.close_ws = function(fig, msg){\n",
+ " fig.send_message('closing', msg);\n",
+ " // fig.ws.close()\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
+ " // Turn the data on the canvas into data in the output cell.\n",
+ " var width = this.canvas.width/mpl.ratio\n",
+ " var dataURL = this.canvas.toDataURL();\n",
+ " this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.updated_canvas_event = function() {\n",
+ " // Tell IPython that the notebook contents must change.\n",
+ " IPython.notebook.set_dirty(true);\n",
+ " this.send_message(\"ack\", {});\n",
+ " var fig = this;\n",
+ " // Wait a second, then push the new image to the DOM so\n",
+ " // that it is saved nicely (might be nice to debounce this).\n",
+ " setTimeout(function () { fig.push_to_output() }, 1000);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._init_toolbar = function() {\n",
+ " var fig = this;\n",
+ "\n",
+ " var nav_element = $('<div/>')\n",
+ " nav_element.attr('style', 'width: 100%');\n",
+ " this.root.append(nav_element);\n",
+ "\n",
+ " // Define a callback function for later on.\n",
+ " function toolbar_event(event) {\n",
+ " return fig.toolbar_button_onclick(event['data']);\n",
+ " }\n",
+ " function toolbar_mouse_event(event) {\n",
+ " return fig.toolbar_button_onmouseover(event['data']);\n",
+ " }\n",
+ "\n",
+ " for(var toolbar_ind in mpl.toolbar_items){\n",
+ " var name = mpl.toolbar_items[toolbar_ind][0];\n",
+ " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
+ " var image = mpl.toolbar_items[toolbar_ind][2];\n",
+ " var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
+ "\n",
+ " if (!name) { continue; };\n",
+ "\n",
+ " var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
+ " button.click(method_name, toolbar_event);\n",
+ " button.mouseover(tooltip, toolbar_mouse_event);\n",
+ " nav_element.append(button);\n",
+ " }\n",
+ "\n",
+ " // Add the status bar.\n",
+ " var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
+ " nav_element.append(status_bar);\n",
+ " this.message = status_bar[0];\n",
+ "\n",
+ " // Add the close button to the window.\n",
+ " var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
+ " 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",
+ " button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
+ " button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
+ " buttongrp.append(button);\n",
+ " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
+ " titlebar.prepend(buttongrp);\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._root_extra_style = function(el){\n",
+ " var fig = this\n",
+ " el.on(\"remove\", function(){\n",
+ "\tfig.close_ws(fig, {});\n",
+ " });\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._canvas_extra_style = function(el){\n",
+ " // this is important to make the div 'focusable\n",
+ " el.attr('tabindex', 0)\n",
+ " // reach out to IPython and tell the keyboard manager to turn it's self\n",
+ " // off when our div gets focus\n",
+ "\n",
+ " // location in version 3\n",
+ " if (IPython.notebook.keyboard_manager) {\n",
+ " IPython.notebook.keyboard_manager.register_events(el);\n",
+ " }\n",
+ " else {\n",
+ " // location in version 2\n",
+ " IPython.keyboard_manager.register_events(el);\n",
+ " }\n",
+ "\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
+ " var manager = IPython.notebook.keyboard_manager;\n",
+ " if (!manager)\n",
+ " manager = IPython.keyboard_manager;\n",
+ "\n",
+ " // Check for shift+enter\n",
+ " if (event.shiftKey && event.which == 13) {\n",
+ " this.canvas_div.blur();\n",
+ " // select the cell after this one\n",
+ " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
+ " IPython.notebook.select(index + 1);\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
+ " fig.ondownload(fig, null);\n",
+ "}\n",
+ "\n",
+ "\n",
+ "mpl.find_output_cell = function(html_output) {\n",
+ " // Return the cell and output element which can be found *uniquely* in the notebook.\n",
+ " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
+ " // IPython event is triggered only after the cells have been serialised, which for\n",
+ " // our purposes (turning an active figure into a static one), is too late.\n",
+ " var cells = IPython.notebook.get_cells();\n",
+ " var ncells = cells.length;\n",
+ " for (var i=0; i<ncells; i++) {\n",
+ " var cell = cells[i];\n",
+ " if (cell.cell_type === 'code'){\n",
+ " for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
+ " var data = cell.output_area.outputs[j];\n",
+ " if (data.data) {\n",
+ " // IPython >= 3 moved mimebundle to data attribute of output\n",
+ " data = data.data;\n",
+ " }\n",
+ " if (data['text/html'] == html_output) {\n",
+ " return [cell, data, j];\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ " }\n",
+ "}\n",
+ "\n",
+ "// Register the function which deals with the matplotlib target/channel.\n",
+ "// The kernel may be null if the page has been refreshed.\n",
+ "if (IPython.notebook.kernel != null) {\n",
+ " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
+ "}\n"
+ ],
+ "text/plain": [
+ "<IPython.core.display.Javascript object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "<img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlgAAAGQCAYAAAByNR6YAAAgAElEQVR4nO3dWZAc1Z3v8SNiwiZiHDzMBPaMifEDcV/suHNDjhthhycmGsnGZhMebMzYYmxjsBljZAZEd6Zt7iyawde+Ax4Pg2GwurKgu9GCQJbQxiIjW4BAErKQENoXkJBaUkvd6n2pqqz//z5UdWe1WksvVXVOVn4/EfVAUt11kv7T/19nnnPSGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnDLNvNBxmTFmmu2BAAAAuMMLlhsv3Wm8YOmEv/aFjssuXZfRU5m8Aq4byos+eCinQ3mxPRTggqjV5KhAV4cz/PRM0xDcOJWAdWyQgAX3dedEL12X0e4cTQtuo1aTowJdHU5pSM0gYKHWdedEL19P04L7qNXkqEBHR1nUB3XGS68yfnB8mp9W4wc3jXmPl5pjvOCw8YIh4webzdzgM2PeM8WAxS8BAAAmblK9H1VQ33id8YOfmvrUV88ZsLzU142fzpiG1O2m/tefMn7QaLx0p2l44qOj3kfAAgCg6qaUAVAd5wxYfrDZeOnHogPzLjFe0Gq81I9HvY+ABQBA1U2q4aO6xgSsW+Z9yHjpcOxVrXSz8YIVo46NN2Dd8+iHzT2PXjbyeuLNKy5dl9E9vaF250QHwyhoZfKi3bnCq7/keK7keF/J8VCi4z0lgU1Kjp8d5EqP5yX6d70lx3Mlq3D6wuh4tuT4QMnx0lU7QyVj5dzif26nM3kdnjNYa+dWyz+3JJ5bRzaq1Vo7t1r+uU3m3MqTAFBRYwKWn/74ND+tpiH9uVFvbEg9ZPxg88g/e8ErxgtOGy89YLz0sTHvL+Wn5k3z0zry+kmLXrouM/Ly9udGCufJ1nDk+Owd2ZHja9vzI8frtkTHd/VGx6/ckBn1P1DpZ5S6fH10/OhgVLSf3pQdOb6xK5qAP2tbdHxpW3T8rt25keOPHAlHjj94KMe51dC5Pf5B7Z5bLf/cknhuz7eFNXtutfxzm8y5lT8NoOzGHbC84GHjpTdN6kO4gsW5xfjcuILFucXl3LiClZxzm1LjR3VM6RbhZBXnYHVl2aYB7hv+RS0iF38zYBG1mhxl6cWorPNOcveDX0UH5l1ivPSxMZPcJ4tJ7gAATFpZejEq4O7HP2K8xunGa5w+zU+r8YK5xmucbu6d/wljTLRNQ31wm7kv9UnjpecbL91p7k19bEqf66XmGD/YbR5o2UvAAgBgcsoRBVAJDakZoyadF1/GD5qi9wQ/NH5wxPjpjPGDzaZh/mfL9vnFK1it7OSOGOjJiV65ITNqDgTgImo1GaRrkICF8+BROYiR7hzPd0M8UKu1TcK8yrI9KjcsImDhPAhYiBGaFuKCWq1dsvOUyndXqtQ1qdQ1EbBwHsWAdYZVhIiBUER39eY1ZGUWHEet1h7pGlT5fxtGgpVcv0hl2R4CFs7CJHcAAC5KRFTWvady87NRuPrZ6ypnBlSVSe44H7ZpAADgnORwl8r9L0fBavZvVN5tG/Ue220crioGrBND3CKE+/pC0bot2VE7LAMuolbjTfoyKvO3qny+pRCsrm5ReWqbylBuzHttt3G4iknuiBEmDiMuqNV4klxe5ZmdKtcujK5a/egVlaPd5/0a220criJgIUZoWogLajV+ZPsJldueH3078PUjF/06220crioGrI4MAQvuy+VF17bnRz38FXARtRofcrpf5V/WR8HqxsUqq/erjPNnZ7uNwzWsIgQAJJiIqKw9FN0OnNGs8os3VbqHJvR9bLdzuIpVhACAhJH3O1XmlqwO/P5qlf0dk/petts4XMUqQsRIfyg6e0dW+1mZBcdRq26S/uzo1YFffFqlabtKNpz097TdxuEqJrkjRpg4jLigVt0i+ztUvN+qfHXJuFcHjpftNg5XEbAQIzQtxAW16gbpHlL5j40qVzVFweprz6m8fkSlTI8xst3G4apiwDrNKkLEQCYv+mRrqBlWZsFx1KpdkheVFw6ozFocBau6JpXgbZX+bFk/y3Ybh6uY5A4AqCGy+7TKnauiUHXb8ypbj1fs82y3cbiGbRoAADVEsmFhAvvw7cBrF6oselclV9k7NLbbOVxVvILVxipCxMBgKOrtz+kgK7PgOGq1umTr8cLO68NXrR58TaVjoCqfbbuNw1VMckeMMHEYcUGtVoe096v88++jYHXTEpVX3qvqGGy3cbiKgIUYoWkhLqjVyhp5KPM1CwrBamazyi83qvRlqj4W220crioGrFOsIkQMDOVFHzyU0yFWZsFx1GplSJgvPN7m1mXRVau7VqscmNwu7OVgu43DVawiBADEgGw/UVgRePZDmcu0n9Vk2W7jcBUBCwDgMGnvV/m3V6Ngdf1ClZZ3yr6f1WTZbuNwFbcIESNDedFHjoTcdoHzqNWpk1xe5dldKtcvKgSrq5pUHnpDpWfI9tBGsd3G4Zqz9sFikjvigInDiAtqdWpk5ymV766Mrlp9b6XKvnbbwzon2+0crmIVIWKEpoW4oFYnRzKhysNvRsHqhkUqK/aphO72KNttHK4qBqyTbDSKGBgIRe/andMBNm+E46jViZO3WlW+sTQKVz/foHKmOpuFToXtNg5XMckdAGCRnOwdvVnoV5aovHrY9rDGzXYbh6sIWAAAC0Y2C712YSFYzWhW+c9NzqwOHC/bbRyuKgasdlYRIgayedGlbXnNsjILjqNWz03aBwqvnadUvrMiumr1gzUqB+1tFjoVtts4XMUkd8QIE4cRF9TqaNKXUXnsrShQnb1ZqMOT2C/GdhuHqwhYiBGaFuKCWi0QEZWXDxYewnx2uPrZ6yqdg7aHOGW22zhcVQxYJ1hFiBjoC0VnbctqHyuz4DhqVVXe71SZ80IUqG5dpvLkNpVfvKmy+5Tt4ZWN7TYO15y10WjS/8oCAJSHdA0WQtTM5kKw+tKCwqNtMqHtoVWE7XYOV7GKEABQBpIXlRcPFuZVDV+1emCdysle20OrKNttHK4qBqwOVhEiBnJ50Y1dec2xMguOS1qtysEzKneuioLVbc+rbDthe1hVYbuNw1VMckeMMHEYcZGUWpVsqPKb3SrXF/eyunahytM7VLK1eTvwXGy3cbiKgIUYSUrTQvwloVbl3TaVby+PrlrduUqlvd/2sKrOdhuHq4oB6zgBCzHQmxP99Kas9tZw00JtqOValbY+lQdfU7mqGKy+/IzK83tVcsnsI7bbOFzFJHcAwDhILl+4HTj8aJvhBzJ3D9kemlW22zhcRcACAFyEbGlV+WbJ7cC71qjsbbc9LCfYbuNwVTFgdWaTeWkX8ZIX0aODonnhDwK4rVZqVdoHVP7t1dGPtlm2J9aPtik3220crmKSO2IkCROHURviXqty8Exhs9Dh24EzmlX+a7NKb8b20Jxju43DVQQsxEjcmxaSI661Ku0DhWA1ozm6avX3q7gdeAG22zhcRcBCjHTnRC9fH7+mheSJW61KmFdZvV/lmgVRsGr4rcrv31dJyGapk2W7jcNVTHIHgESTd9tU7lg5+orV9mTswl4Otts4XMPDngEg0aSjeDtwOFhdv1Bl0buJ3c9qsmy3c7iKK1gAkCiSDVWe2xU93qauSeVnr6t0DtoeWizZbuNwFXOwECNxnTiM5HG1VuXdNpVvLouC1fdWJuahzJViu43DVQQsxIirTQs4m2u1Kqf7C1ephoPVTc+orNjHflZlYLuNw1UELMSIa00LOB+XalVW71f5UnF14FXFx9twO7BsbLdxuKoYsLrYyR0xICLanROVmO+OjdrnQq1K56DKv78RXbX6wRqVXaesjadW2W7jcBWT3AGgpkg2VFmyU+WGRVG4+o+N/GFSIbbbOFxFwAKAmiG7T6vctToKVrevUNnRZntYNc12G4erigGrlTlYiIGenOiVGzLawx8EcFy1a1XOFPe0uqoYrK5bWJh7xST2irPdxuEqJrkjRlyaOAxcSLVqVfKisnJf9FDmuiaVB19Taeur6OciYruNw1UELMQIAQtxUY1alX3tKt8vuR14J4+4scF2G4erigHrDKsIEQOhiO7qzWvIZF04rpK1OrKn1fDtwGuLj7jhocxW2G7jcBWT3AEgFiQvKi8eVPnyM9FVq399VaW93/bQEs12G4erCFgA4CQJ8yrrD6u8eljlQIfKnBdGrw7cyZ5WLrDdxuGqYsA6McQtQrivLxSt25LVvpA/COC2qdaq7GhTuWNlFKiGX9csUFmwQ2UwV+YRY7Jst3G4iknuiBEmuSMuJlurcqRL5Z9+PzZY1TWp/Mt6lZO9lRkwJs12G4erCFiIEQIW4mKitSqZUOWZnSpfaCmEqRnNKg+9oXKqT2X5HpXd3A50le02DlcVA1ZHhoAF9+Xyomvb85pjtRQcN5FalY1HVWb/JrpS1bBW5b0zVRglysF2G4drvNQc4we7zQMte7kiAADVJwc6VLzfRsHqK0tUVuxju4WYsd3O4SpWEQJAVUlfpvDw5eFg9fkWlf/eotKftT00TILtNg5XsYoQMdIfis7ekdV+VhHCceeqVQnzKi8eULn52ShczVuvcrTb4kgxVbbbOFzFJHfECJPcERdn16q8fULl28ujYPWNpSpbj1seJcrBdhuHqwhYiBECFuJipFbPDI7eduGGRSoL32Ufqxpiu43DVcWAdZpVhIiBTF70ydZQM0wChuMymVA3Ne7Q/HULC8FqZrPKL95U6cnYHhrKzHYbh6uY5A4AZSMiKq8dGX078LbneaxNDbPdxuEqAhYAlIUcOqNy/8tRsLpxscrq/Wy7UONst3G4qhiw2lhFiBgYDEW9/TkdZBUhHCPvdxYCVV2TyhdaNPvrP+g/b+ujVhPAdhuHq5jkjhhhkjtcIz0ZlcathTlWdU0q31mhcrSbWk0Q220criJgIUZoWnCF5PIqK/dFV63qmgq3B9v6VJVaTRLbbRyuKgasU6wiRAwM5UUfPJTTIea0wCLZ0qpyx4ooWH1zucqrh0e9h1pNDtttHK5ikjsAjIv0ZFT+a/PoSexLdqpkQ9tDg0W22zhcRcACgAuSXPERN6W3A3+5UaVjwPbQ4ADbbRyu4hYhYmQoL/rIkZDbLqgKEVHZelzl9pLbgd9arrLhg4t+LbWaHLbbOFzFJHfECBOHUS3S2qPywLooWM1arLJwx7hvB1KryWG7jcNVBCzECE0LlSZ5UXlmZ7TtwudbCrcDOwcn9H2o1eSw3cbhqmLAOslGo4iBgVD0rt05HWDzRlSAbD85+hE39WtVDnZM6ntRq8lhu43DVUxyB5Bw0tqj8uNXomB1/SKVZXtUhN+LuDjbbRyuImABSCjpyag8sknl6pZCsJrRrPLvb6j0ZGwPDTFiu43DVcWA1c4qQsRANi+6tC2vWVZmYQokL4UrVF9dEl21uu8llcNdZfsMajU5bLdxuIpJ7ogRJg5jqqStb/TqwNm/KezMXubbgdRqcthu43AVAQsxQtPCZEkmVGneXlgVWNek8oUWled2qwxVZhd2ajU5bLdxuKoYsE6wihAx0BeKztqW1T5WZmGcRERl7aHRtwP/4SWV3acr+rnUanLYbuOoJK9xlvGDfcYPDhgv+N6EvpZJ7gBqlGw7oXLXmihY3fysyssHWR2IsqpQZ4d1M+b9kfHS+83cJ64wdz/+EeMH+8zc4E/G/fUELAA1QvKisv2EyoYPCqsBh4PV1U+rtLyjkuGhzCi/CnZ4WHV/418ZL1g+8s9e8IjxUrPH/fXFgNXBKkLEQC4vurErrzlWZuEs8vYJlduej0LV8OuhN1Taq/9QZmo1OSrR2lEO9UGd8dKrjB8cn+an1fjBTWPe46XmGC84bLxgyPjBZjM3+Ez09amvGS/92Mg/+2nPeEHDuD+fSe6IESYO42xy8IzKP/8+ClTXLlT53srCSsEdbdbGRa0mx9RCACqnvvE64wc/NfWpr54zYHmprxs/nTENqdtN/a8/Zfyg0XjpTtPwxEcL/z64ZUzA8lP14/58AhZihKaFYdIxoPL4W9EzA+uaVB5+U6VnyPbQVJVaTZLyhAFU1DkDlh9sHhWgzLxLjBe0Gi/1Y2PMuW8RNgS3nvdD7nn0w+aeRy8beT3x5hWXrsvovt5Qu3OigyUrXjJ50e5c4dVfcjxXcrx0hUwo0fGekl8qUnL87F82pcfzJRNPe0uOl15i7wuj46Ub+A2UHB8qOT5UMlbOLf7n1pHJ6//amNHjg/maO7da/rmV9dyGQh1s2aH5q5+OgtX/+Z327u1w6tw6s1Gt8nOr7XMrbxJARYwJWLfM+5Dx0uHYq1rpZuMFK4wxhUnufnBg1CT3OY/96Xk/xE/Nm+andeT1kxa9dF1m5OXtz40UzpOt4cjx2TuyI8fXtudHjtdtiY7v6o2OX7khetREd05GfUapy9dHx48ORkX76U3ZkeMbu6Kra7O2RceXtkXH79qdGzn+yJFoIuuDh3KcG+fGudXAuYmI9r9wQA/+zdIoWN21WmXj0difWy3/3JJwbpVJBCirMQHLT398mp9W05D+3Kg3NqQeMn6wueR9XzZeer/xgoPGT/39BT/kPFewjg3m+euFc+PcODcnz036Miq/eHMkWIWzFmv/qv2jtluI67nV8s8tKedW3iSAihh3wPKCh42X3lSWDy3OwerMMgcL7suL6NHB0b+IUbskl1dZ+K7K9QsL4eqqJpWntqsMZC/+xZZRq8lRll6MyprULcKpYpI7YqQ7x8ThJJC8qKw/rHLHyuh24LeWj9wOjANqNTnK0otRWeed5O4Hv4oOzLvEeOljI5Pcp4qAhRihadU+OXhGZc4LUbC6fpHKmv0qMdtPilpNjrL0YlTA3Y9/xHiN043XOH2an1bjBXON1zjd3Dv/E8aYaJuG+uA2c1/qk8ZLzzdeutPcm/rYlD7XS80xfrDbPNCyl4CFuOjOiV6+nqZVi+SDrsLeVcPB6poFKsHbKp2Dtoc2KdRqcpQjCqASGlIzRq3qK76MHzRF7wl+aPzgiPHTGeMHm03D/M+W7fN5VA4Ai6Q3o9K8vfA4m+Fw9U+/VznZa3towLiUrR+jxhCwAFgiLx5QuW5hFKzmvqzyfqftYQETYruNw1UELABVJm19ox/GfNvzKmsPjdp2AYgL220crmKSO2KEicPxJoO5sY+3eXJb7Cawjwe1mhy22zhcwyR3xBBNK54kG6q8cEBl9m+iYHXvSypvn7A9tIqhVpPDdjuHq7iChRihacWPvHVM5Rslj7e5+dlY7Wc1WdRqcthu43BVMWB1sZM7YmD4kRvM1XGfvHNS5UevRMHqpiUqi95V6ctc/ItrALWaHLbbOFzFJHcAZSRnBlT+ZX0UrGY0qzy6WaXf/cfbAJNhu43DVQQsAGUgnYOFCes3LCoEq5nNKg+9ofJBl+2hARVlu43DNWdNcm9lDhZioCcneuWGzKin2cM+2dIaBau6JpXbV6jsbbc9LKuo1eSw3c7hKia5I0aYOOwW6c+qtLwTbbvwnRUq695XCfl9Qq0mh+02DlcRsBAjNC03SC6vsmDH6KtWP3tdZSi0PTRnUKvJYbuNw1XFgHWGVYSIgVBEd/XmNWRlljWy+7TKd1dGwWr2bwp7XPEzGYVaTQ7bbRyuYpI7gHGQ7ScLzwocDlazFheeJcjtQCSc7TYOVxGwAFyAdA0Wbv8NB6uZzSr/93WVjgHbQwOcYLuNw1XFgHViiL9C4b6+ULRuS1b7Qv4gqDRp71eZ/weV6xcWgtVVTYVtF4732h5aLFCryWG7jcM1PIsQMcTE4cqTMK/yzE6VLz49etuFd9tsDy1WqNXksN3O4SpWESJGaFqVIyIqW4+rfH91FKzuWqOy4QOVPP+9J4paTQ7bbRyuKgasjgwBC+7L5UXXtuc1R8MvK9l1SuXOVVGwum6hyqp9rAycAmo1OWy3cbiKSe5AosmJ3sKKwLqmwm3B/9ykcqrP9rCA2LDdxuEqAhaQWDIURleu7lyl0jloe0hA7Nhu43AVqwgRI/2h6OwdWe1nZdaUSV9G5cHXCuHqxsUqJ1gdWE7UanLYbuNwFZPcESNMHJ466c2opLaO3n7hrWO2h1VzqNXksN3G4SoCFmKEpjU18tYxlZufjSazf2u5ymtHbA+rJlGryWG7jcM1Z+2DdZpVhIiBTF70ydZQM6zMmhBp7VH5+YbRzw989TDbL1QQtZoctts5XMUkd6BmybHuwjyrmc1RuPrPTSoDWdtDA2qG7TYOVxGwgJojubzKondVri7Zjb1hLbuxAxVgu43DVcWA1cYqQsTAYCjq7c/pICuzzklEVDYdU/neyihY3feSyt5220NLHGo1OWy3cbiKSe6IESYOn5uIqKw/rPLdkmB1/SKVNfvZjd0SajU5bLdxuIqAhRihaY0lp/tVfvRKFKyuWaDy2FsqHQO2h5Zo1Gpy2G7jcFUxYJ1iFSFiYCgv+uChnA6xMkslzKu8cEDlhkWFYPWFFpXgbZUudmN3AbWaHLbbOFzFJHcgViQTqqzcV9hqYfiq1Z2rVA6dsT00IJFst3G4ioAFxIbsa1f52+eiYDVrscrCd1VyXIEGbLHdxuEqbhEiRobyoo8cCRN520VePazypQWFYPXVJSpLdqr0s5+Vq5Jcq0lju43DNWft5M4kd8RBEicOS5hXeXpHdNWqfq1Kb8b2sHARSazVpLLdzuEqVhEiRpLUtCQbqqzer3LrstG7sHM7MBaSVKtJZ7uNw1XFgHWSjUYRAwOh6F27czpQw5s3iojKbw+pfO2suVYr9toeGiYgCbWKAtttHK5ikjvgDDkzoPKPv4uC1U1LVJ5hrhXgMtttHK4iYAHWSV5U1r2ncuPiQrCa2azy1HaVodD20ABchO02DlcVA1Y7qwgRA9m86NK2vGZrZGWW5PIqaw+p3PZ8dNXqOytU9vHswLirtVrF+dlu43AVk9wRI7UycVhEVF55T+UbS6Ngde1Clae2qWS5alULaqVWcXG22zhcRcBCjNRC05K2vtHPDrxxsUrLOyo9bL1QS2qhVjE+tts4XFUMWCdYRYgY6AtFZ23Lal8MV2ZJXlSW7SlcqRp+duBT21UGmMBei+Jcq5gY220crmKSO1BRksurvHhA5ZvLo6tWP1ij8n6n7aEBKAPbbRyuImABFSGZsHDF6paS/ayuX6jy3G6VkCvGQK2w3cbhqmLA6mAVIWIglxfd2JXXnOMrs2TPaZVvl1yx+ptnVBbuUOljnlVSxKVWMXW22zhcw7MIEUOuTxyWTKiS2lrYx2o4WC3bozKUsz00VJnrtYrysd3O4SpWESJGXG5asutUYQ+r4atW89ardA7aHhYscblWUV622zhcVQxYxwlYiIHenOinN2W115GmJSIqW4+rzH05ClZffkZl/WHbQ4NlrtUqKsd2G4ermOQOTJiIqGw4onLX6ihYzWxW+dnrXLUCEsZ2G4erCFjAhMhQWAhSw8Hq6qdV/nOTyole20MDYIHtNg5XFQNWZ5ZbhHBfXkSPDormxc4fBHK6P7pqNbNZ5Yk/qHQMWBkL3Ga7VlE9tts4XMUkd8SIzYnDsuuUyleWFMLVDYtUtrRWfQyIDya5J4ftNg5XEbAQIzaaloiorNmvcnVLIVzd9rzKse6qfT7iiYCVHLbbOFxFwEKMdOdEL19fnaYlYV7ld++r3LEymm/1wDqVfp4diIurZq3CLtttHK5ikjswSvTswGVRsLpmgUrzdhV25QZwFtttHK4iYAEj5K1jKl9fWvLswEUqT25T6R6yPTQAjrLdxuEqAhag0p9V+cWbPDsQwITZbuNwFXOwECOVmDgs20+ofKPkqtUjm1QGmGeFqWGSe3LYbuNwFQELMVLOpiVDOZVfvaVyVTFY3fKcytbjZRglQMBKEtttHK4iYCFGytG0ZCinsnS3yteei65a/fsb3A5EWRGwksN2G4erigGri53cEQMiot05UZnE7tjSlynMq/qbZ6JgdfOzKm8ercBIkXRTqVXEi+02DlcxyR01TnqGCisBr18UBau/Xary/F6VodD28ADEnO02DlcRsFCjRERl3fsqXy65YvXN5SovHlTJccUWQHnYbuNwjZeaY/xgt3mgZe+l6zLayhwsxEBPTvTKDRntucgfBHK6v7Dr+nCw+tbywq7sIXWO6hhvrSL+bLdzuIpJ7oiRi00cFhGVVftUrl9YCFafb1F5aptKlluBqC4muSeH7TYOVxGwECMXalrS2qNy30vRVavvr1Y5dMbCKAECVpLYbuNwVTFgnWEVIWIgFNFdvXkNS1ZmSVufyn9tVrn66UKw+uLTKs/s5HYgrDpXraI22W7jcBWT3BFTcrS7sH/V51uiq1b3vaRyrNv20AAkiO02DlcRsBAzcqBDZd56lRnNUbC69yWVLa3sOQSg6my3cbiqGLBODHE7BW6To92a81+JQlVdk8qPXlF5t8320IAx+kLRui1Z7QsJ/bXOdhuHq5jkDsdJXlSe21WYW1XXpGFdk2b+eb3KgQ7bQwPOi0nuyWG7jcNVBCw4TFp7VO55ceSKVfbel/R/PnuapgXnEbCSw3Ybh6uKAasjQ8CCO0REZfkelWsWFMLVlxaoLNujuVxe17bnNZenacFtubxQqwlhu43DVUxyh2PkZK/K3JejeVb3vKjS2mN7WABwTrbbOFxFwIIjJMyrrNyncu3CaD+r53arcAUAgMNst3G4ilWEsEyyocrq/Sq3LouuWt29RuWDrjHv7Q9FZ+/Iaj8rs+A4ajU5bLdxuIpJ7rBEBrKF1YE3PxsFq1mLL7gLOxOHERfUanLYbuNwFQELVSY9QyrN2/0jDrwAABaySURBVFVuXBwFq68sKQSr/uwFv5amhbigVpPDdhuHq4oB6zSrCFFh0jGg8us/RHOs6ppUvrFUZcU+lUw4ru+RyYs+2RpqhnlZcBy1mhy22zhcxSR3VIG8fULlhkVRsLrteZW1h1RyBHsA8Wa7jcNVBCxUmLxwIHog8x0rVDYcYWUggJphu43DVcWA1cYqQpSZ5EWlcWt01epf1qsM5ab0PQdDUW9/TgdZmQXHUavJYbuNw1VMckcFyFBOZd76KFw1bi3LVSsmDiMuqNXksN3G4SoCFspMOgdVfrCmEKxmNqus2V+2703TQlxQq8lhu43DVcWAdYpVhCgDeb9T5etLC+Hq+kUqW4+X9fsP5UUfPJTTIeZwwXHUanLYbuNwFZPcUSay9bjK9Quj7RcOj92JHQBqje02DlcRsFAGsnp/4Xbg8GNuOgdtDwkAqsJ2G0clecFy46U7jRcsnfDXcosQUyDdQyqPbo4ms//rqypD49s0dDKG8qKPHAm57QLnUavJUYGuDmf46ZmmIbhxKgGLSe6YCOkcVJm/VeWaBVG4Ct5Wkco2EyYOIy6o1eSoQFeHUxpSMwhYqDTpHCw87qY0WN2xQuWND6ry+TQtxAW1mhwV6OgYl/qgznjpVcYPjk/z02r84KYx7/FSc4wXHDZeMGT8YLOZG3xmwp8zxYB1ko1GcQHSMaDy31tUvlQSrL67UuX1IxW/alVqIBS9a3dOB9i8EY6jVpNjwn0XZVLfeJ3xg5+a+tRXzxmwvNTXjZ/OmIbU7ab+158yftBovHSnaXjioyPv8dPbjR/sHPtKf3zkPVMMWPyVhXOR9gGVX72l8sWno2B15yqVDR9UNVgBgKsmHxBQNucMWH6w2Xjpx6ID8y4xXtBqvNSPJ/TNxxuw7nn0w+aeRy8beT3x5hXDtwi7czLqsQ6ZvGh3rvDqLzmeKzneV3I8lOh4T0lgk5LjZwe50uP5kobdW3I8VzJJtC+MjmdLjg+UHC+dVDpUMlbObfznJqf7Vf5rs+avLglW31+tsvHomHOO27nV8s+Nc+PcOLfqn9uEejUqY0zAumXeh4yXDsde1Uo3Gy9YMaFvPt6A5afmTfPTOvL6SYteui4z8vL2R8+Ke7I1HDk+e0d25Pja9vzI8bot0fFdvdHxKzdkRv0PVPoZpS5fHx0/OhgV7ac3ZUeOb+yKbl/O2hYdX9oWHb9rd27k+CNHolVsDx7KcW4TOLf/8dqgysIdKle3jASrN29drbPmHx51xcrWuaWO8nPj3OJxbi+cDmv23Gr55zaZc5tQr0ZljAlYfvrj0/y0mob050a9sSH1kPGDzeP+xl7wivGC08ZLDxgvfWzM9yt1nitYe3pD/npJ+Ln1HOvR3A9fjK5Y3b1G+zYe0+5s3plzO50p/JI7Npjn58a5OX1uHdmoVmvt3Gr558YVrJgad8DygoeNl95UlUGxijDxRERl7SGV64q7sF+zQGXNfifnWHXnWJmFeKBWk6MqvRoXVtFbhJNVDFgnWEWYSNIzpDJvfXTV6gdrVI512x7WefWForO2ZUf9ZQm4iFpNjqr0alzYeSe5+8GvogPzLjFe+tiEJ7lPFqsIE0u2Hle5+dlCsJrZrNK0XSVH0AaAiahKr8Y53P34R4zXON14jdOn+Wk1XjDXeI3Tzb3zP2GMibZpqA9uM/elPmm89HzjpTvNvamPVXRcXmqO8YPd5oGWvQSsZJFMWNjT6qriVavZv1HZdcr2sAAgliraq3EBDakZo1btFV/GD5qi9wQ/NH5wxPjpjPGDzaZh/merNr7iFawOnkWYCHLojMrtK6Jbgg+9odKfvfgXOiKXF93YlR816RVwEbWaHFXr14gZJrknguRF5dld0fYLNy5W2XDE9rAmjInDiAtqNTlst3G4ioBV8+RUn8rcl6OrVv5vVdoHbA9rUmhaiAtqNTlst3G4qhiwjhOwao6IqLzynsqsxYVg9cWnVZbvcXL7hfHqzYl+elNWe2lacBy1mhy22zhcwyT3miUiKq8dUbljZXTV6nsrVQ532R4aANQc2+0crmKbhppxzmB1zQKVp7apZMOLfwMAwITZbuNwVTFgdWa5RRhXkheVVw+r3LFidLBKbVXpGrQ9vLLKi+jRwdGP1ABcRK0mh+02DlcxyT22zhmsrl1Yk8FqGBOHERfUanLYbuNwFQErdpIYrIbRtBAX1Gpy2G7jcBUBKzZGgtXtZwWr4G2V7iHbw6uK7pzo5etpWnAftZoctts4XMMqwtggWAGAu2y3c7iKVYTOIlgBgPtst3G4ioDlJDnWrfLDF6JgdR3BCgBcZLuNw1XMwXKKiKg8v7ewzcLwdgsEqxFMHEZcUKvJYbuNw1UELGdIW5/K/SXPDPyHl1SO99oellNoWogLajU5bLdxuIqAZZ2IqLx4oHAbcPiZgc/tVsnzi/lsNC3EBbWaHLbbOFxVDFhd7ORuhbQPqPxkXXTV6q41Kh/wzMDzERHtzkmsH1iNZKBWk8N2G4dr2KbBOvnd+yo3Li4Eqy+0qCzcoRISdAEgTmy3c7iKVYRVJ12DKvPWR1et7lipcvCM7WEBACbBdhuHq4oBq5U5WFUhGz5QuWlJIVjNbFZJb1PJhraHFRs9OdErN2S0hz8I4DhqNTlst3G4iknuVSG9GZWfb4iuWn1rucqe07aHFTtMHEZcUKvJYbuNw1UErIqTLa0qX3uuEKyualL57y0qQ1y1mgyaFuKCWk0O220crioGrDOsIiw7Gciq/HJjdNVq9m9U3jlpe1ixForort68hqzMguOo1eSw3cbhKia5V4S8c7IQqIbD1S83qgxkbQ8LAFBmtts4XEXAKisZCgu3AK8qBqubn1V5q9X2sAAAFWK7jcM1Z+2DdWKIW4RTJXtOFyavD1+1+vkGld6M7WHVlL5QtG5LVvtC/iCA26jV5LDdzuEqJrlPmfRlVFJbC9su1DWp3PSMyoYPbA+rJjFxGHFBrSaH7TYOVxGwJk36Miot76jcsCi6ajVvvUrXoO2h1SyaFuKCWk0O220crioGrI4MAWu8zhmsvrlcZf1h20Orebm86Nr2vOZ4EDYcR60mh+02DlcxyX3czhusfnuIZwgCQELZbuNwFQHrokaC1azFBCsAwCi22zhcVQxYrCIc69zBapnKWoKVLf2h6OwdWe1nZRYcR60mh+02DlcxyX0MgpW7mDiMuKBWk8N2G4erCFgjCFbuo2khLqjV5LDdxuGaszYaPZ3gVYTSnyVYxUQmL/pka6gZVmbBcdRqcthu53BVgie5S39W5ekdo4PV3xGsAADjZ7uNw1UJDFgEKwBAudhu43BVMWC1JWAVIcEq/gZDUW9/TgdZmQXHUavJYbuNw1UJmOR+3mD18kGVXO2edy1i4jDiglpNDtttHK6q4YB1zmB1K8EqzmhaiAtqNTlst3G4qhiwTtXQKkLpz6os2KFyI8Gq1gzlRR88lNMhVmbBcdRqcthu43BVDU1yl2yospBgBQCoHtttHK6qkYAlrT0qd64aHaxeIlgBACrLdhuHq2rgFqH87n2V6xYWgtWsxSovHiBY1aihvOgjR0Juu8B51Gpy2G7jcFWMJ7nLUKjyHxujq1ZzXlBp67M9LFQQE4cRF9Rqcthu43BVTAOWHOlSuX1FFK7mb+WqVQLQtBAX1Gpy2G7jcFUxYJ2M0Uaj8vJBlWsWFILVl59R2XzM9pBQJQOh6F27czrA5o1wHLWaHLbbOFxz1sOe4/BXlgxkVX6+Ibpqde9LKu39tocFAEgw2+0crorJKkJ574zKt5cXgtWMZpWntvN4GwCAdbbbOFxVDFjtjq4iFBGV1ftVvvh0IVx9ZYnK2ydsDwuWZPOiS9vymmVlFhxHrSaH7TYOVzk8yV36syr/9mp0S7BhrcqZAdvDgkVMHEZcUKvJYbuNw1WOBizZ117YLLSuSWVmc2GHdv4STDyaFuKCWk0O220crioGrBOOrCIUEZVle1S+0FIIV197TuXdNtvDgiP6QtFZ27Lax8osOI5aTQ7bbRyucmiSu/RkVP7p99EtwZ+sU+kesj0sAADOy3Ybh6scCViy+5TK3y4tBKvPt6g8u0tF7Ic+AAAuxHYbh6uKAavD0ipCEVF5ZmdhnlVdk8rXl6rsPm1lLHBfLi+6sSuvOebjwXHUanLYbuNwlcVJ7tI1qPKjV6Jbgv/0e5XeTNXHgfhg4jDiglpNDtttHK6yFLDknZMqNz9bCFZXt6g8v5dbgrgomhbiglpNDtttHK4qBqzjVQpYkheVp3dEtwT/bpnKgY6qfDbirzcn+ulNWe2lacFx1Gpy2G7jcFUVJ7lLx4BK/droluCDr6n0Zyv+uQAAVIrtNg5XVSlgydbjKjctKQSrLz6tsmY/twQBALFnu43DVcWA1ZmtzC1CCfMqT25Tuap41eq251XeO1ORz0Lty4vo0UHRPOEcjqNWk8N2G4erKjjJXU73q/zDS9EtwX9/Q2UwV/bPQXIwcRhxQa0mh+02DldVKGDJpmMqNy4uBKtrFqisPVTW749komkhLqjV5LDdxuEaLzXH+MFu80DL3nIGLMnlVX79h+iq1R0rVT7oKsv3Brpzopevp2nBfdRqcthu53BVGSe5y8lelbvXROHqlxtVhsIylC8AAG6y3cbhqjIFLNlwROWGRYVgdd1Cld+/X57KBQDAYbbbOFw1xYAl2VDlV5ujq1Z/v0qltafM5QsAgJtst3G4agqT3KW1R+XOVVG4euwtlSy3BFE5TBxGXFCryWG7jcNVkwxY8rv3C7cC65pUZi1W2fBBZSoXKEHTQlxQq8lhu43DVRMMWDIUqvzHxuiq1ZwXVNr6Kly+QAFNC3FBrSaH7TYOVxUDVtc4dnKXI10qd6yIwtX8rSq56jwkGlBVFRHtzgmPWYLzqNXksN3G4apxTnKXlw8WNgyta1L58jMqm49VqXQBAHCX7TYOV10kYMlAVuXnG6KrVve+pNLeX+XyBQDATbbbOFxVDFit55iDJe+dUfn28kKwmtGs8tR2lZBbgrCnJyd65YaM9jCvBY6jVpPDdhuHq84xyV1EVFbvV/ni04Vw9ZUlKm+fsFi+QAEThxEX1Gpy2G7jcNVZAUv6syr/9mp0S7BhrcqZAcvlCxTQtBAX1Gpy2G7jcFUxYJ3J5lX2tavcuqwQrGY2qyzcoZLnlwPcEYrort68hqzMguOo1eSw3cbhquFtGpbtVflCSyFcfe05lXfbbNcsAADOs93G4arhgHV1cQuGH7+i0jVou14BAIgF220crioGrM5rF6k8u4tN8eC0vlC0bktW+0LqFG6jVpPDdhuHq4oB6/g7p2zXKHBRTBxGXFCryWG7jcNVk3zYM2ADTQtxQa0mh+02DlcVA1ZHhoAF9+Xyomvb85pjdSscR60mh+02DleN81mEAABgLNttHK4iYAEAMGm22zhcVQxYJ4a4RQj39Yeis3dktZ+VWXActZoctts4XMUkd8QIE4cRF9Rqcthu43AVAQsxQtNCXFCryWG7jaNS7n/8L4yXXm/8YLfx0zuMF9wyoa8vBqzTrCJEDGTyok+2hpphZRYcR60mR4W6O6y7b/6fG69xujHGGO/xPzNe0GoaHv7jcX89k9wBAJi0SrV3uMYL3jH3P/4X434/AQsAgEmrYEfHBdUHdcZLrzJ+cHyan1bjBzeNeY+XmmO84LDxgiHjB5vN3OAzk/us1P82frBzQl9TDFhtrCJEDAyGot7+nA6yMguOo1aTY1L9GmVQ33id8YOfmvrUV88ZsLzU142fzpiG1O2m/tefMn7QaLx0p2l44qMj7/HT240f7Bz7Sn985D1zgz8xXnqXub/xryY0Pia5I0aYOIy4oFaTY2ohAWVxzoDlB5uNl34sOjDvEuMFrcZL/Xjc3/ieRz9svOA14wffGtd773n0spHXE29ecem6jG7pyumxwby2DeW1OyfanRM9ncnrscHC60TJ8Y7zHD+TjY63DkbHu0qOHys53p2TUcc7s9G/O15yvCMTHT8xFB1vLzl+suT4qZLjp0rGyrnF/9ze6w/10nUZ3dMb1ty51fLPLYnndnjg3LVaC+dWyz+3yZybeaHjMmPMtHH3bJTfmIB1y7wPGS8djr2qlW42XrBivN/W+MFi46fmjevdfmreND+tI69/XKSXrsvw4sWLFy9evCb5KoYs2DImYPnpj0/z02oa0p8b9caG1EPGDzaP65vWz/9r46WlcBux+Jo7/y/P+/6zr2DNbb5i2j8uUvPEm1eYFzouq4nXAy17a+Zzy/E9J/s9JvJ1433veN53ofc88eYV037SUjv1aqtWK/XZtup1ol9TrnpNUq2W6+fr0udO9fuWfj1XsOwad8DygoeNl95UlUHd8+hl0/y0mnserZ307Qe7a+Zzy/E9J/s9JvJ1433veN53offUWr3aqtVKfbatep3o15SrXpNUq8bU1u/Wcnxfm///YrQK3SKcmlr8JeCl5tTM55bje072e0zk68b73vG870LvqbV6tVWrlfpsW/U60a8pV70mqVaNqa3freX4vjb//8Vo553k7ge/ig7Mu8R46WMTmuQ+FbX4SwC1i3pFXFCrQIXd/fhHjNc43XiN06f5aTVeMNd4jdPNvfM/YYyJtmmoD24z96U+abz0fOOlO829qY9VZXz3PPph46fmmXse/XBVPg+YCuoVcUGtAhXWkJoxatVe8WX8oCl6T/BD4wdHjJ/OGD/YbBrmf9begAEAAAAAAAAAAAAAAAAAAAAAcJHXOMv4wT7jBweMF3zP9nCAC/KC5cZLdxovWGp7KMAF3f/4Xxgvvd74wW7jp3cYL7jF9pAAVMuMeX9kvPR+M/eJK8zdj3/E+ME+Mzf4E9vDAs7LT880DcGNBCw47775f268xunGGGO8x//MeEGraXj4jy2PCkBV3N/4V8YLlo/8sxc8YrzUbIsjAi6uITWDgIXY8YJ3zP2P/4XtYQAYj/qgznjpVcYPjp9zB3ljCtv8e8Fh4wVDxg82m7nBZ6KvT33NeOnHRv7ZT3vGCxqqMnYkz1TrdRgBC9VQrno1xpj61P82frCz0kMGUC71jdcZP/ipqU999Zy/AIZ3kG9I3W7qf/0p4weNxkt3moYnPlr498EtYwKWn6qv6jkgOaZar8MIWKiGctXr3OBPjJfeZe5v/KtqDh9AmZz3GYilAcrMu8R4QevIMxDPdYuwIbi1KgNGok2qXocRsFBlk67Xex79sPGC14wffKtaYwVQZmN+Adwy70PGS4dj/+pKNxsvWGGMKUxy94MDoya5z3nsT6s6cCTSpOp1GAELVTbJep1m/GCx8VPzqjdSAGU35heAn/74ND+tpiH9uVFvbEg9ZPxgc8n7vmy89H7jBQeNn/r7qg0YiTbpevWCV4wXnDZeesB46WNj3g9UwKTqtX7+XxsvLcZPbx95zZ3/l1UdOICpG/cvAC942HjpTdUeH1CKekWcUK9Agk3plgtQZdQr4oR6BRLsvJMw/eBX0YF5lxgvfWzMpGGgyqhXxAn1CiTN3Y9/xHiN043XOH2an1bjBXON1zjd3Dv/E8aYaBlxfXCbuS/1SeOl5xsv3WnuTX3M8siRRNQr4oR6BRKsITVjmp/Ws1/GD5qi9wQ/NH5wxPjpjPGDzaZh/mftDRiJRr0iTqhXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADiv/w9w8KXvxvlLCgAAAABJRU5ErkJggg==\" width=\"600\">"
+ ],
+ "text/plain": [
+ "<IPython.core.display.HTML object>"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "frob_export_for_blog(simulate_bitslide(data), svgfile='/tmp/corrected_brightness_sim.svg')"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.5"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}