FiniteVolumeGPU/Desingularization.ipynb
2018-08-03 16:01:34 +02:00

4149 lines
362 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydCbxNVfvHf+YpojRIIkmGeEWzpJSMIfWmASmVyJA3paKoaEBSMg9RVCJUMmQolEalVDKUSJpk+Ms8/T/PPvZ1Xefetc9d+zl7n3N++/PxeXvvXWs9a39/z1rruWvttVaOQ4cOHQIfEiABEiABEiABEiCBlCGQgwFgymjNFyUBEiABEiABEiABhwADQDoCCZAACZAACZAACaQYAQaAKSY4X5cESIAESIAESIAEGADSB0iABEiABEiABEggxQgwAEwxwfm6JEACJEACJEACJMAAkD5AAiRAAiRAAiRAAilGgAFgignO1yUBEiABEiABEiABBoD0ARIgARIgARIgARJIMQIMAFNMcL4uCZAACZAACZAACTAApA+QAAmQAAmQAAmQQIoRYACYYoLzdUmABEiABEiABEiAASB9gARIgARIgARIgARSjAADwBQTnK9LAiRAAiRAAiRAAgwA6QMkQAIkQAIkQAIkkGIEGACmmOB8XRIgARIgARIgARJgAEgfIAESIAESIAESIIEUI8AAMMUE5+uSAAmQAAmQAAmQAANA+gAJkAAJkAAJkAAJpBgBBoApJjhflwRIgARIgARIgAQYANIHSIAESIAESIAESCDFCDAATDHB+bokQAIkQAIkQAIkwACQPkACJEACJEACJEACKUaAAWCKCc7XJQESIAESIAESIAEGgPQBEiABEiABEiABEkgxAgwAU0xwvi4JkAAJkAAJkAAJMACkD5AACZAACZAACZBAihFgAJhigvN1SYAESIAESIAESIABIH2ABEiABEiABEiABFKMAAPAFBOcr0sCJEACJEACJEACDADpAyRAAiRAAiRAAiSQYgQYAKaY4HxdEiABEiABEiABEmAASB8gARIgARIgARIggRQjwAAwxQTn65IACZAACZAACZAAA0D6AAmQAAmQAAmQAAmkGAEGgCkmOF+XBEiABEiABEiABBgA0gdIgARIgARIgARIIMUIMABMMcH5uiRAAiRAAiRAAiTAAJA+QAIpQGDcuHG4/fbb0940V65cOPXUU1G3bl306dMHJUuWdH734Ycf4sorr8QHH3yAK664IiYyS5Yswfvvv4/77rsPRYsWjSmvKfGkSZPwxBNP4Oeff8bu3bvx9ddfo1q1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eApFqYcCVIsqqYcZnub4bc7uRgQNoIUOhw4dQpUqVfDll1+iUqVKFjUVLCoX8FtvvYUrr7wSaWlpodbNyuInQD3iZ6ZZgnpo0o2/buoRPzPNEtTDTFcMYO3atXHw4EFUrlzZXCAFI2gALUT96quvvA7EgwRIgARIgARIIPkIyATOr3/96+RreAgtpgG0gJidnY09e/agYsWKOOussyxqKljU/+1EY3Yx1IaWkMqoh1tCUw/q4RYBt1rD68Osx08//YTDhw/jvPPOQ6lSpcwFUjCCBtBRUfl+glvCUA/q4RYBt1rD64N6uEWArQlCgAYwCKViiOENtRigx0hJPaiHWwTcag2vD+rhFgG2JggBGsAglIohhjfUYoBOA+gWdOpBPZKGgFsN5fjhlh6utoYG0FFlTpw4gUceeQT//Oc/cfbZZzvaypLTLOrhltbUg3q4RcCt1vD6cEsPV1tDA+iqMmwXCZAACZAACZAACSgRoAFUAstqSYAESIAESIAESMBVAjSArirDdpEACZAACZAACZCAEgEaQCWwrJYESIAESIAESIAEXCVAA+iqMmwXCZAACZAACZAACSgRoAFUApu/2okTJ+KJJ57A3r17kZGRgXHjxqFt27ZFZp87dy6GDx+OrVu3omHDhhg9ejS6deuWGy+7mI8aNQqTJ0/G999/j5YtW2LChAle3TzMBMLW45ZbbsG0adPOSCyafPDBB+bGMALx6LFhwwaMGDECq1evxs6dOzF27FgMGjSoAMV46qQEBQnEwy+IJvfff793z8p71KhRA19//TXxByAQjx7PPfccXnrpJXz22WdezS1atMDDDz+MSy+9lGNIANYlJYQGMAKlZ8+ejZtuuskb5Nq0aYNJkyZhypQpyMrKQp06dQq0IDMz0zOHDz74oGf65s2b5w1477//vmf05Hjsscc8Uzh16lRccMEFeOihh/Dee+9h06ZN3qfpeBRNQEMPMYD79u3Diy++mJu4bNmyqFq1KqUwEIhXj48++givvPKKN6gNHjwY99xzTwEDGG+dFOlMAvHyC6KJGMBXX30VS5cuzU1WunRp/OpXvyL+kK+RXr16eWNN69atUa5cOTz++ON47bXXIEa9Vq1aHEPY4zwCNIARdAQxbc2bN8czzzyTm61x48bo2rWrt9df/uP666+HbOS5cOHC3B916tQJ6enpmDVrFmT2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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib notebook\n",
"\n",
"from matplotlib import rc\n",
"#rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})\n",
"#rc('text', usetex=True)\n",
"\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"\n",
"\n",
"desing_eps = 0.001\n",
"h = np.linspace(0, 150*1.5*desing_eps, 200)\n",
"u = np.linspace(0.5, 0.5, 200)\n",
"hu = h*u\n",
"\n",
"k = desing_eps**2*0.05\n",
"u_desing1 = h*hu/(h**2+k)\n",
"\n",
"t = np.minimum(1.0, h/desing_eps)\n",
"u_desing1 = (1-t)*u_desing1+t*u\n",
"\n",
"u_desing1 = np.sqrt(2)*h*hu/np.sqrt(h**4+np.maximum(h**4, desing_eps))\n",
"k = desing_eps**4\n",
"u_desing2 = np.sqrt(2)*h*hu/np.sqrt(h**4+np.maximum(h**4, k))\n",
"\n",
"fig=plt.figure()\n",
"plt.plot(h, u, 'k:+', markevery=3)\n",
"plt.plot(h, u_desing1, 'r-+')\n",
"plt.plot(h, u_desing2, 'k-.')\n",
"plt.xlabel('h')\n",
"plt.ylabel('u')\n",
"plt.title('Plot of f(x) = sin(x)')\n",
"plt.grid(True)\n",
"plt.show()\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4Xu3dCXgV9fn28TsJRAz7KrKEgAqyiYCyBRD7YqtWy6J/EJFN6oqK2vdVa12gAgpUwKogS5VFQUTArdr6VytKwGKpiICA7KuCIpuYBJK812/qSQUCOec8SeYs37kuri7MM2fmM3fyPJw5MychLy8vTywIIIAAAggggAACcSOQwAAYN+eaA0UAAQQQQAABBDwBBkCCgAACCCCAAAIIxJkAA2CcnXAOFwEEEEAAAQQQYAAkAwgggAACCCCAQJwJMADG2QnncBFAAAEEEEAAAQZAMoAAAggggAACCMSZAANgnJ1wDhcBBBBAAAEEEGAAJAMIIIAAAggggECcCTAAxtkJ53ARQAABBBBAAAEGQDKAAAIIIIAAAgjEmQADYJydcA4XAQQQQAABBBBgACQDCCCAAAIIIIBAnAkwAMbZCedwEUAAAQQQQAABBkAygAACCCCAAAIIxJkAA2CcnXAOFwEEEEAAAQQQYAAkAwgggAACCCCAQJwJMADG2QnncBFAAAEEEEAAAQZAMoAAAggggAACCMSZAANgnJ1wDhcBBBBAAAEEEGAAJAMIIIAAAggggECcCTAAxtkJ53ARQAABBBBAAAEGQDKAAAIIIIAAAgjEmQADYJydcA4XAQQQQAABBBBgACQDCCCAAAIIIIBAnAkwAMbZCedwEUAAAQQQQAABBkAygAACCCCAAAIIxJkAA2CcnXAOFwEEEEAAAQQQYAAkAwgggAACCCCAQJwJMADG2QnncBFAAAEEEEAAAQZAMoAAAggggAACCMSZAANgnJ1wDhcBBBBAAAEEEGAAJAMIIIAAAggggECcCTAAxtkJ53ARQAABBBBAAAEGQDKAAAIIIIAAAgjEmQADYJydcA4XAQQQQAABBBBgACQDCCCAAAIIIIBAnAkwAMbZCedwEUAAAQQQQAABBkAygAACCCCAAAIIxJkAA2CcnXAOFwEEEEAAAQQQYAAkAwgggAACCCCAQJwJMADG2QnncBFAAAEEEEAAAQZAMoAAAggggAACCMSZAANgEZ3wjz76SGPHjtXy5cu1e/duLVy4UN27dy+irZ+8mbS0NG3duvWkv7j99tv17LPPFtvrsmEEEEAAAQQQiH4BBsAiOofvvPOOMjIy1KpVK11zzTXFPgDu3btXOTk5+Xu/atUqXXbZZfrHP/6hLl26FNFRsRkEEEAAAQQQiEUBBsBiOKsJCQknDYDZ2dl66KGH9NJLL2n//v1q1qyZRo8eXWTD2t1336233npLX331ldzrsyCAAAIIIIAAAqcSYAAshmwUNAD27dtXW7Zs0RNPPKFatWp5A6IbCL/44gudd955pr1ww6Xb5r333qsHH3zQtC2KEUAAAQQQQCD2BRgAi+EcnzgAbty40RvyduzY4Q1qgaVr165q06aNRo0aZdqLV155Rddff722bdt23PZNG6UYAQQQQAABBGJWgAGwGE7tiQPgvHnz1KtXL5UtW/a4V8vKylLPnj01d+5c793B+vXrn3ZvhgwZomeeeeakdX71q18pOTlZb775ZjEcDZtEAAEEEEAAgVgTYAAshjN64gDoBjx3CXj16tVKSko67hXLlSunmjVr6ujRo3LvFJ5uqVy5ss4666zjVnF3Ajdo0EALFixQt27diuFo2CQCCCCAAAIIxJoAA2AxnNETB8D169erUaNGco+K6dSpU5G+4rBhwzR58mRt375dpUqVKtJtszEEEEAAAQQQiE0BBsAiOq+HDx/Whg0bvK21bNlS48aN06WXXqoqVaooNTVVN9xwg/eYmCeffNL7+2+//VYffPCBmjdvriuvvDKsvcjNzfUuG/fp08e7uYQFAQQQQAABBBAIRoABMBilINb58MMPvYHvxGXAgAGaPn26d4l3xIgRmjlzpnbu3KmqVauqffv2Gj58uDcEhrO8++67cp//W7dunRo2bBjOJqhBAAEEEEAAgTgUiJkBMJxv4li0aJH36BT32Tx3d+59992nW2+9NQ5jwCEjgAACCCCAQDwJxMwAGOo3cWzevNl7GPNNN92kW265xbs8675Gbc6cOd43ebAggAACCCCAAAKxKhAzA+DPT1BBD2I+8QTef//9euONN/Tll1/m/5V79+/zzz/X0qVLY/V8c1wIIIAAAggggIDidgDs3LmzdzPGU089lR8D9+0c7nl9R44cUenSpYkHAggggAACCCAQkwJxOwC6myYGDhx43FenLVmyROnp6dq1a5fOPvvsk064e3Cz+xNY3F24+/bt827o4Pt3Y/Lng4NCAAEEEIhBgby8PB06dMj7/H9iYmIMHmHhhxTXA+CgQYP0+9//Pl/JfQ6wY8eO2r17t/dw5hMX98w9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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"(0, 1e-07)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def desing1(x, eps):\n",
" return np.maximum(x, eps)\n",
"\n",
"def desing2(x, eps):\n",
" t = np.maximum(0.0, np.minimum(1.0, 1.0 - np.abs(x) / eps))\n",
" #return (1.0 -t) * x + t * eps*(0.5 + 0.5*np.cos(np.minimum(t * np.pi, np.pi)))\n",
" return eps*(0.5 - 0.5*np.cos(np.minimum(x / eps * np.pi, np.pi)))\n",
" \n",
"eps = np.float32(4.0e-8)\n",
"x = np.linspace(0.0, 1e-7, 100)\n",
"y = desing2(x, eps)\n",
"\n",
"plt.figure()\n",
"plt.plot(x, y)\n",
"plt.ylim(0, 1e-7)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x9c0a16ec18>"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"eps = np.float32(2.0e-22)\n",
"x = np.linspace(0, 1.5*eps, 500).astype(np.float32)\n",
"y = np.maximum(np.minimum(x*x/(np.float32(2.0)*eps)+np.float32(0.5)*eps, eps), x)\n",
"\n",
"plt.figure()\n",
"plt.plot(x, x, label='orig')\n",
"plt.plot(x, y, label='limited')\n",
"plt.xlabel('x')\n",
"plt.xlabel('Desingularized')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuzdB3gVVf7/8U8qIZAEAoQaQHqHJCACorLqrnVpdgWCKOq6FlzXrj8QAVdWAddViihFQUQFXRV1XRVWEIVI6EV6CR0SEkLqzf854yZ/qbnkpNzynufh2f9P5syc85rP5Xz/M/fMDSgoKCgQGwIIIIAAAggggIDfCARQAPrNtWagCCCAAAIIIICAI0ABSBAQQAABBBBAAAE/E6AA9LMLznARQAABBBBAAAEKQDKAAAIIIIAAAgj4mQAFoJ9dcIaLAAIIIIAAAghQAJIBBBBAAAEEEEDAzwQoAP3sgjNcBBBAAAEEEECAApAMIIAAAggggAACfiZAAehnF5zhIoAAAggggAACFIBkAAEEEEAAAQQQ8DMBCkA/u+AMFwEEEEAAAQQQoAAkAwgggAACCCCAgJ8JUAD62QVnuAgggAACCCCAAAUgGUAAAQQQQAABBPxMgALQzy44w0UAAQQQQAABBCgAyQACCCCAAAIIIOBnAhSAfnbBGS4CCCCAAAIIIEABSAYQQAABBBBAAAE/E6AA9LMLznARQAABBBBAAAEKQDKAAAIIIIAAAgj4mQAFoJ9dcIaLAAIIIIAAAghQAJIBBBBAAAEEEEDAzwQoAP3sgjNcBBBAAAEEEECAApAMIIAAAggggAACfiZAAehnF5zhIoAAAggggAACFIBkAAEEEEAAAQQQ8DMBCkA/u+AMFwEEEEAAAQQQoAAkAwgggAACCCCAgJ8JUAD62QVnuAgggAACCCCAAAUgGUAAAQQQQAABBPxMgALQzy44w0UAAQQQQAABBCgAyQACCCCAAAIIIOBnAhSAfnbBGS4CCCCAAAIIIEABSAYQQAABBBBAAAE/E6AA9LMLznARQAABBBBAAAEKQDKAAAIIIIAAAgj4mQAFoJ9dcIaLAAIIIIAAAghQAJIBBBBAAAEEEEDAzwQoAP3sgjNcBBBAAAEEEECAApAMIIAAAggggAACfiZAAehnF5zhIoAAAggggAACFIBkAAEEEEAAAQQQ8DMBCkA/u+AMFwEEEEAAAQQQoAAkAwgggAACCCCAgJ8JUAD62QVnuAgggAACCCCAAAUgGUAAAQQQQAABBPxMgALQzy44w0UAAQQQQAABBCgAyQACCCCAAAIIIOBnAhSAfnbBGS4CCCCAAAIIIEABSAYQQAABBBBAAAE/E6AA9LMLznARQAABBBBAAAEKQDKAAAIIIIAAAgj4mQAFoJ9dcIaLAAIIIIAAAghQAJIBBBBAAAEEEEDAzwQoAP3sgjNcBBBAAAEEEECAApAMIIAAAggggAACfiZAAWhxwV0ul1JSUhQREaGAgACLI9EUAQQQQAABBMpLoKCgQOnp6apXr54CAwPL67QedR4KQIvLsXv3bsXGxlocgaYIIIAAAgggUFECu3btUoMGDSrq9BV6XgpAC/60tDRVq1ZNJkCRkZEWR6IpAggggAACCJSXwLFjx5wbOKmpqYqKiiqv03rUeSgALS6HCZAJjikEKQAtIGmKAAIIIIBAOQowf0sUgBaBI0AWeDRFAAEEEECgggSYvykAraJHgKz4aIwAAggggECFCDB/UwBaBY8AWfHRGAEEEEAAgQoRYP6mALQKnjsBMkvN8/LylJ+fb3UuGp+/QFBQkIKDg3lFz/nT0QIBBBDwaQF35m+fBhAFoNX1LS5AOTk52rt3rzIzM63OQ+OSC4SHh6tu3boKDQ0t+UFoiQACCCDgUwLFzd8+NdizDIZFIBZX+VwBMi+J/uWXX2TuQtWqVcspQHhZtAX2eTY1d15NAX7w4EHn7mvz5s399mWf50nH7ggggIDPC1AAcgfQKuTnClBWVpa2bdumRo0aydyFYqsYAXP3dceOHbrgggsUFhZWMZ3grAgggAACHiVAAUgBaBVIdwpACg8rYuvGhYU418GakgMggAACPiNAAUgBaBVmCkArvnJpTAFYLsycBAEEEPAqAQpALykAx4wZo48++kgbNmxQ5cqV1b17d/3tb39Ty5Ytzxm4Dz/8UM8++6y2bNmipk2batSoUerbt29RG/M9sREjRmjy5Mk6evSounbtqn/+859q27atW0H21QLwsssuU6dOnTR+/Hg1btxYDz/8sPOnpNvw4cM1f/58JScnl/QQZ22XmJjo/JSPOf6ZNgrAUifngAgggIDXC1AAekkBeNVVV+mWW25Rly5dnFeqPP3001q9erXWrVunKlWqnDGIP/zwg3r27KmRI0c6Rd+8efP03HPP6fvvv3cKPbOZItIUhdOmTVOLFi30wgsvaNGiRdq4caMiIiKKDbg/FIBmEYUxtvkeY0ZGhrKzs1WjRg3HtLiirVj43+xQ3LEoAM9Hk30RQAAB/xCgAPSSAvDUOJqiJCYmRgsXLtQll1xyxrTefPPNMhd4wYIFRX9vCsnq1atr9uzZMnf/6tWr59zZevzxx519TJFSu3ZtpzC85557iv0U+EMBWCxCCXYormg7n0MWdywKwPPRZF8EEEDAswRcrgIFBgaUeqcoAL20ANy8ebPzWg9zF7Bdu3ZnDEbDhg01bNgw50/hNm7cOOexplkVunXrVuex8M8//6y4uLiifXr37q1q1app+vTppx3XFIjmT+FmAhQbG6u0tDRFRkaetL83Fx7negRsXmUzceJE/etf/9I333zjrHJ+6623nFfd3HXXXVq2bJk6dOigd955x/E1228fAZv/t3ns/tvt22+/lTnnnj179Mgjj+irr75yXtly8cUXa8KECc5jaLOZ17n89a9/dc5nXq8zZMgQ7d+/3/HnEXCp//vIARFAAIEKFVi1O1WPfbBKkwYkqFGNMz/tK2kHKQC9sAA0d+5MkWa+s/ff//73rNfevHfPPNq97bbbivaZNWuWBg8e7BRxS5YsUY8ePZyiw9wJLNyGDh3qFIhffvnlacc+U/FidnK3ADR9P5Fb/r8IUjkk6LzeQVhcAVi/fn298sorzvcEzd1T892+Jk2a6LHHHpMpvO+8806niC68+/rbAtA8DjaFm/nwvf32245xdHS082jfHM88tjd3Zc0veJhH8klJSVq1apXzHsWXXnpJo0eP1tSpU9WmTRu9/PLLev/99/W73/2OArCk/wrSDgEEEPBAgS/W7NXDc5KVlevS1e3q6I07Ekq1lxSAXlgA3n///frss8+c7/I1aNDgnAWguYt36623Fu3z7rvvOsWHuTtXWACmpKQ4vxRRuN19993atWuXvvjii9OObXsHMDMnT22eO72wLNVUn+Fg657/g8JDg90+TXEF4DPPPON8t9JsS5cuVbdu3ZyizBR+ZnvvvfecQvvEiRPO/33qIpAzPbY1d/VMgbd+/fqiYtW8yNkUkubu3u9//3unUH/ooYeKHtmbotG83iUhIYEC0O2ry44IIICA5wqYGyWTFm3Viws2OJ28tEUtvXZbnCLCQkq10xSAXlYAPvDAA85EbxZqmIn/XFtZPAI+9Xzn+x1AXykAzV23G2+80eEwL7s2d/9++uknZ5GO2cwjXXNXrvDOqDsFoCnsJ02adNrLms2LnM3KbHMn1xSDp37v0yzwMf9g8Ai4VP9t5GAIIIBAuQvk5rv07Pw1em/ZLufcA7s10nPXtVFwUGCp94UC0EsKQDPBm+LPrOT97rvvnO//FbeZRSDp6en6/PPPi3a9+uqrnSLit4tAzHcEzaNLs5k7TmZxSVktAvGVR8DmOvTp08cx2759u1OMr1ixwnmEazZzjXr16uU8pjfe7hSA9913n/N9THOX9tTNfL/QbBSAxaWev0cAAQS8UyAtM1f3vZukJVsOy6z5ePa6Nhrc49w3emxGSgHoJQXgn/70J5nv73388ccnvfsvKirKeS+g8/9TGDhQ5rtp5p2BZjOPeM0KYfOaF/OdQdPWPLo89TUwZn/zXTRTVJrvl5nihdfAnP09gGYRiG0BaL5nuXfvXmchSeE2ZcoU59GuKShPXVBTuE/hqu3Cgt08AjZ3H+Pj47kDaPMvIW0RQACBChTYcfi47py2TFsOHld4aJD+cWucLm9du0x7RAHoJQWgKTrOtJnCzXyfzGzme2tmtahZ+FG4ffDBB07RV7ji1xSD/fr1K/r7whdBm0ePv30R9NlWFp/ah/N9BFymaS7Fgxf3HUDbAtAU2sbcrPY17wY0hXxubq5zB9EU8c8//7zz/c6dO3c6LwA3K3/N/23uzJo/5vuGrVu3dhaimO8bsgikFC8+h0IAAQTKUWD59iMaOjNJR47nqG5UmKYO6qI29U5+q0ZZdIcC0EsKwLK4+KVxTArAkj0CNu9xvP3222Ve1m1WBRe+Bmbfvn3OXUDz2N48vjfF4OWXX66///3vzl1Bc8fv0Ucfde7YmtfEmEUnhw4d4jUwpRFmjoEAAgiUs8DHyXv017mrlJPvUvv6UZo6qLNiIsPKpRcUgBSAVkHz1QLQCsXDGnvz+xg9jJLuIIAAAqUiYJ6+TfjPLxr/9S/O8X7fprbG39LpvN5WYdsRCkAKQKsMUQBa8ZVLYwrAcmHmJAgggIBbAlm5+Xriw1Wan5zi7H/PJU30+FWtyuTXPs7VIQpACkC3Anu2nSgArfjKpTEFYLkwcxIEEECgWIHDGdm6Z2aSlu84qqDAAI3s3U63dW1YbLuy2IECkALQKlcUgFZ85dKYArBcmDkJAgggcE6BzQcynJW+O49kKiIsWG/cnqCLm9esMDUKQApAq/BRAFrxlUtjCsByYeYkCCCAwFkFFm8+pPveSdKxrDzFRlfW24ld1CwmokLFKAApAK0CSAFoxVcujSkAy4WZkyCAAAJnFJizbKeenrdGea4CxTespskDO6tm1UoVrkUBSAFoFUJ3CkDzbsLCl1VbnYzGJRIwv0dc+GslYWHl83qBEnWURggggIAPCbhcBfrblxs0aeFWZ1R/7FhPL93QQWEhQR4xSgpACkCrIJ4rQPn5+dq0aZPz03LmZcdsFSNw+PBhHThwQC1atFBQkGf8w1MxEpwVAQQQKB+BEzn5GjYnWV+s3eec8KHLm+vhK5rrbD/qUD69OvksFIAUgFa5Ky5A5ufOUlNTnSIwPDzco8JvNXAvaGzeM5WZmekUf+Y3hOvWresFvaaLCCCAgHcLHDiWpbtmLNeq3WkKDQp07vr1iavvcYMqbv72uA6XQYcCCsxMyVYigeICZGjNr1uYIpCtYgRM8VenTh2K74rh56wIIOBHAutSjmnI9GXam5al6CqhmjQgQV0aR3ukQHHzt0d2upQ7RQFoAepugMzjYPNbt2zlKxASEsJj3/Il52wIIOCnAt9s2K8HZq3Q8Zx8NalVxVnp26hGFY/VcHf+9tgBlELHKAAtEAmQBR5NEUAAAQR8QmDa4m16/tN1chVI3ZvWcN7xFxUe4tFjY/7mO4BWASVAVnw0RgABBBDwYoG8fJdGfrpO03/Y4Yzips4N9EKf9goNDvT4UTF/UwBahZQAWfHRGAEEEEDASwUysvP0wKyf9e3Gg84Inri6lfO7vp600vdctMzfFIBWHz0CZMVHYwQQQAABLxTYk3pCQ6Yt04Z96QoLCdS4mzrp6vbe9aYF5m8KQKuPHgGy4qMxAggggICXCazclaoh05frUEa2akVU0psDO6tjbDUvG4XE/E0BaBVaAmTFR2MEEEAAAS8S+GLNXj08J1lZuS61qhOhqYldVL9aZS8awf/vKvM3BaBVcAmQFR+NEUAAAQS8QMC803bSoq16ccEGp7eXtaylf9wap4gwz17pey5a5m8KQKuPHgGy4qMxAggggICHC+TkufTs/DWas3yX09PE7o31zLWtFRzk+St9KQDPHS7eA2jx4aMAtMCjKQIIIICARwukZebqvneTtGTLYQUGSM9d10aJPS7w6D672znmb+4AupuVM+5HgKz4aIwAAggg4KECOw4f1+Bpy7T14HFVCQ3Sa7fFq1erGA/t7fl3i/mbAvD8U/ObFgTIio/GCCCAAAIeKLBs+xENnbFcRzNzVS8qzFns0bpupAf2tORdYv6mACx5esQycis8GiOAAAIIeJzA/BV79NgHq5ST71KHBlHOa15iIsM8rp+2HaIApAC0yhABsuKjMQIIIICAhwiYlb7jv/5FE/7zi9Ojq9rW0bibO6lyaJCH9LB0u8H8TQFolSgCZMVHYwQQQAABDxDIys137vp9sjLF6c29lzbVY39oqUCz8sNHN+ZvCkCraBMgKz4aI4AAAghUsMDhjGwNnZmkpB1HFRwYoFF92+nmLg0ruFdlf3rmbwpAq5QRICs+GiOAAAIIVKDA5gPpzkrfXUdOKDIsWBPvSFD3ZjUrsEfld2rmbwpAq7QRICs+GiOAAAIIVJDA4s2HdO87SUrPylPD6HC9ldhFzWKqVlBvyv+0zN8UgFapI0BWfDRGAAEEEKgAgdk/7XR+3SPPVaDOjapr8sDOiq4SWgE9qbhTMn9TAFqljwBZ8dEYAQQQQKAcBVyuAv3tiw3O7/qarU+nenqxfweFhfjmSt9z0TJ/UwBaffQIkBUfjRFAAAEEykkgMydPw+Yk68u1+50zDruihR68vJkCAnx3pS8F4LnDxW8BW3z4KAAt8GiKAAIIIFAuAvuPZemu6cu1ek+aQoMCNfbGDurdqX65nNtTT8L8zR1Aq2wSICs+GiOAAAIIlLHAupRjGjJ9mfamZTnf85s8IEGdG0eX8Vk9//DM3xSAViklQFZ8NEYAAQQQKEOBbzbs1wOzVuh4Tr6a1qqitxMvVMMa4WV4Ru85NPM3BaBVWgmQFR+NEUAAAQTKSODtxds08tN1chVIPZrV0Ou3JyiqckgZnc37Dsv8TQFolVoCZMVHYwQQQACBUhbIy3fp+U/XacYPO5wj39IlViP7tFNIUGApn8m7D8f8TQFolWACZMVHYwQQQACBUhRIz8rVn2et0MJNB2UW9z5xVSsNvaSJ3670PRct87eXFICLFi3S2LFjlZSUpL1792revHnq06fPWa9tYmKipk+fftrft2nTRmvXrnX++/DhwzVixIiT9qldu7b27dvn9seRALlNxY4IIIAAAmUosPtopoZMW66N+9MVFhKo8TfH6ap2dcrwjN59aOZvLykAFyxYoMWLFys+Pl79+/cvtgBMS0vTiRMnitKZl5enjh076oEHHnAKv8IC8IMPPtDXX39dtF9QUJBq1arldqoJkNtU7IgAAgggUEYCybtSnde8HMrIVkxEJb05qLM6NKhWRmfzjcMyf3tJAfjbuJmXVhZ3B/DUeM6fP1/9+vXTtm3b1KhRo6IC0Pz35OTkEqeZAJWYjoYIIIAAAqUgsGD1Xj08J1nZeS61rhupqYM6q161yqVwZN8+BPO3nxSA119/vbKzs/XVV18VJdrcCTSPlaOiolSpUiV17dpVo0ePVpMmTc6aenMM86dwMwGKjY2VueMYGRnp258WRocAAggg4DECBQUFemPhFr30xUanT79rFaNXb41T1UrBHtNHT+4IBaAfFIDmO4OmSJs1a5Zuuummojyax8qZmZlq0aKF9u/frxdeeEEbNmxwviNYo0aNM+b2TN8bNDtSAHryx5y+IYAAAr4lkJPn0tPzVmtu0m5nYIN7NNYz17ZRUKB//qxbSa4uBaAfFIBjxozRyy+/rJSUFIWGhp41J8ePH1fTpk312GOP6ZFHHjnjftwBLMnHjDYIIIAAAqUlkJqZo3vfSdLSrUdk6r3hf2yrgd0al9bh/eY4FIA+XgCaW+TmDt91112ncePGFRvsK6+8Us2aNdMbb7xR7L5mBwLkFhM7IYAAAgiUgsD2Q8d15/Rl2nrwuPOo9x+3xalXy5hSOLL/HYL528cLwO+++069evXS6tWr1a5du3Mm3NzdM3cAhw4dqueee86tTwMBcouJnRBAAAEELAV+2nZEQ2cuV2pmrupFhemtwV3Uqg7fPS8pK/O3lxSAGRkZ2rx5s3Od4+Li9MorrziFXXR0tBo2bKgnn3xSe/bs0YwZM07KwoABA/TLL79o6dKlp2Xk0UcflVkcYtofOHDA+Q7gwoULnWKxcKVwccEiQMUJ8fcIIIAAArYC81bs1uMfrFZOvksdG0RpyqDOiokIsz2sX7dn/vaSArDwTt6paR00aJCmTZsm8+Ln7du3y+xXuJmFGXXr1tWECRN09913nxb0W265ReYF04cOHXLe/XfRRRdp5MiRMi+LdncjQO5KsR8CCCCAwPkKmK8xjfv3Jr36za83QK5pX0cv39hJlUODzvdQ7H+KAPO3lxSAnppcAuSpV4Z+IYAAAt4tkJWbr8c+WKVPVqY4A7nvsqb66+9bKpCVvqVyYZm/KQCtgkSArPhojAACCCBwBoHDGdm6e8Zy/bwzVcGBARrdt71u6hKLVSkKMH9TAFrFiQBZ8dEYAQQQQOAUgV/2pzsrfXcdOaHIsGBNHJCg7k1r4lTKAszfFIBWkSJAVnw0RgABBBD4jcD3vxzSfe8mKT0rT41qhOutxC5qWqsqRmUgwPxNAWgVKwJkxUdjBBBAAIH/Ccz6caee/XiN8l0F6tK4uiYN6KzoKmf/8QLg7ASYvykArRJEgKz4aIwAAgj4vYAp+F5csF5T/rvNsegbV18v9m+vSsGs9C3LcDB/UwBa5YsAWfHRGAEEEPBrgcycPD38XrK+WrffcRh2RQs9eHkzBQTwm75lHQzmbwpAq4wRICs+GiOAAAJ+K7D/WJaGTF+mNXuOKTQ4UGNv6KDener7rUd5D5z5mwLQKnMEyIqPxggggIBfCqxNSdOQacu171iW8z2/KQMTlNAo2i8tKmrQzN8UgFbZI0BWfDRGAAEE/E7g63X79eB7K5SZk69mMVX11qAualgj3O8cKnrAzN8UgFYZJEBWfDRGAAEE/EbA/KzbW4u364XP1qmgQLq4WU398/Z4RVUO8RsDTxoo8zcFoFUeCZAVH40RQAABvxDIy3dpxL/WaebSHc54b72woZ7v3VYhQYF+MX5PHCTzNwWgVS4JkBUfjRFAAAGfFziWlas/z1qhRZsOyizuffqa1hpy8QWs9K3gK8/8TQFoFUECZMVHYwQQQMCnBXYdyXRW+m7an6HKIUEaf0sn/aFtHZ8es7cMjvmbAtAqqwTIio/GCCCAgM8K/LzzqIbOWK5DGTmKiaikqYO6qH2DKJ8dr7cNjPmbAtAqswTIio/GCCCAgE8KfLoqRX95f6Wy81xqXTdSbyV2Vt2oyj45Vm8dFPM3BaBVdgmQFR+NEUAAAZ8SMCt9X/9ui8Z+udEZ1+WtYvTqrXGqUinYp8bpC4Nh/qYAtMoxAbLiozECCCDgMwLZefl66qM1+vDn3c6Y7uxxgZ6+trWCAvlZN0+8yMzfFIBWuSRAVnw0RgABBHxC4OjxHN37TpJ+3HZEpt4b/se2GtitsU+MzVcHwfxNAWiVbQJkxUdjBBBAwOsFth06rjunLZP536qVgvXabXG6rGWM14/L1wfA/E0BaJVxAmTFR2MEEEDAqwWWbj3s3PlLzcxV/WqV9VZiF7WsE+HVY/KXzjN/UwBaZZ0AWfHRGAEEEPBagQ+SduvJj1YpN79AHWOracrABMVEhHntePyt48zfFIBWmSdAVnw0RgABBLxOwOUq0Cv/3qTXvt3s9P3a9nX18k0dFRYS5HVj8ecOM39TAFrlnwBZ8dEYAQQQ8CqBrNx8PTp3pT5dtdfp9/29muovV7ZUICt9veo6ms4yf1MAWoWWAFnx0RgBBBDwGoGD6dkaOnO5VuxMVUhQgEb3ba8bO8d6Tf/p6MkCzN8UgFafCQJkxUdjBBBAwCsENu1Pd1b67j56QlGVQzTxjgR1a1rDK/pOJ88swPxNAWj12SBAVnw0RgABBDxeYNGmg7r/3Z+Vnp2nxjXCnZW+TWpV9fh+08FzCzB/UwBafUYIkBUfjRFAAAGPFnj3xx167uO1yncV6MLG0Zo0IEHVq4R6dJ/pnHsCzN8UgO4l5Sx7ESArPhojgAACHilgCr4xn6/Xm99vc/rXL66+xvRvr0rBrPT1yAtWgk4xf1MAliA2/78JAbLiozECCCDgcQKZOXl6cHayvl6/3+nbX65soT//rpkCAvhNX4+7WBYdYv6mALSID8vIrfBojAACCHiYwL60LA2ZvkxrU44pNDhQf7+xo/7YsZ6H9ZLulIYABSAFoFWOCJAVH40RQAABjxFYsyfNKf72H8tWjSqhmjywsxIaVfeY/tGR0hVg/qYAtEoUAbLiozECCCDgEQL/XrdfD85eoRO5+WoeU9VZ6RsbHe4RfaMTZSPA/E0BaJUsAmTFR2MEEECgQgUKCgo09fttGvX5ehUUSBc3q6l/3h7vvOuPzbcFmL8pAK0SToCs+GiMAAIIVJhAbr5L//fJWs36cafTh9u6NtSIP7ZVSFBghfWJE5efAPM3BaBV2giQFR+NEUAAgQoROJaV67zc+b+/HJJZ3Pv0Na015OILWOlbIVejYk7K/E0BaJU8AmTFR2MEEECg3AV2Hcl0ftbtlwMZqhwSpFdvjdOVbWqXez84YcUKMH9TAFolkABZ8dEYAQQQKFeBn3ce1dAZy3UoI0e1Iytp6qAualc/qlz7wMk8Q4D520sKwEWLFmns2LFKSkrS3r17NW/ePPXp0+esKfruu+/Uq1ev0/5+/fr1atWqVdF///DDD/Xss89qy5Ytatq0qUaNGqW+ffu6nU4C5DYVOyKAAAIVKvDpqhT95f2Vys5zqU3dSGelb52osArtEyevOAHmby8pABcsWKDFixcrPj5e/fv3d7sA3LhxoyIjI4sSVqtWLQUF/fpTPj/88IN69uypkSNHOkWfKSqfe+45ff/99+ratatbqSRAbjGxEwIIIFBhAmal7z+/3ay/f7XJ6cMVrWM04ZY4VakUXGF94sQVL8D87SUF4G+jYn6Ox907gEePHlW1atXOmLSbb75ZJgCmuCzcrrrqKlWvXl2zZ892K50EyC0mdkIAAXvs5hIAACAASURBVAQqRCA7L19PfbRGH/682zn/nT0u0NPXtlZQID/rViEXxINOyvzt4wVg48aNlZWVpTZt2uiZZ5456bFww4YNNWzYMOdP4TZu3DiNHz9eO3bsOGNMs7OzZf4UbiZAsbGxSktLO+lOowdlnK4ggAACfilw9HiO7n0nST9uO+IUfMP/2FYDLmrklxYM+nQBCkAfLQDNo1/zvcGEhASnYJs5c6YmTpwo893ASy65xElCaGiopk2bpttuu60oGbNmzdLgwYNPKvJ+G5vhw4drxIgRpyWJApB/XhBAAAHPEdh6MMNZ6bv9cKYiKgXrtdvjdWmLWp7TQXpS4QIUgD5aAJ4pWddff73zjqdPPvmkqACcPn26br311qLd3333XQ0ZMsS5a3imjTuAFf6ZpQMIIIDAOQWWbj3s3PlLzcxV/WqVncUeLetEoIbASQIUgH5UAJoVvu+8847MSmCzleQR8KmfHwLEvygIIICA5wh8kLRbT360Srn5BeoUW01TBnZWrYhKntNBeuIxAszfflQA3nDDDTpy5Ii++eYbJ4BmEUh6ero+//zzokBeffXVzqIRFoF4zGeUjiCAAALFCrhcBXrl35v02rebnX2vbV9XL9/UUWEhv771gQ0BbuCcnoGAArNG3sO3jIwMbd786wc7Li5Or7zyirOgIzo62rmT9+STT2rPnj2aMWOGs49ZyGEWgLRt21Y5OTnOnb8XX3xR5r1//fr1c/ZZsmSJ831Ac2ewd+/e+vjjj52FIrwGxsPDQPcQQACB3whk5ebrL3NX6rNVe53/+udezfTIlS0UyEpfcnIOAe4AeskdwLO92HnQoEHOQo7ExERt377dWeRhtpdeekmTJ092isLKlSs7haApEq+55pqT4vDBBx84Rd/WrVuLXgRdWCC688khQO4osQ8CCCBQNgIH07N194zlSt6VqpCgAI3p10E3JDQom5NxVJ8SYP72kgLQU1NHgDz1ytAvBBDwdYFN+9M1+O1l2pN6QlGVQzRpQIIualLD14fN+EpJgPmbAtAqSgTIio/GCCCAQIkEFm46qPvf/VkZ2Xm6oGYVTR3UWU1qVS3RsWjknwLM3xSAVsknQFZ8NEYAAQTOW2Dm0h0a/sla5bsKdOEF0Zp0R4KqVwk97+PQwL8FmL8pAK0+AQTIio/GCCCAgNsCpuAb9dl6vbV4m9Omf3wDjenXXqHBgW4fgx0RKBRg/qYAtPo0ECArPhojgAACbgkcz87TQ++t0NfrDzj7//UPLfWny5o6L/dnQ6AkAszfFIAlyU1RGwJkxUdjBBBAoFiBvWknNGTacq3be0yVggOd9/td16Fese3YAYFzCTB/UwBafUIIkBUfjRFAAIFzCqzenaa7ZizT/mPZqlk11Pllj7iG1VFDwFqA+ZsC0CpEBMiKj8YIIIDAWQW+XLtPD7+XrBO5+WpRu6qmDuqi2OhwxBAoFQHmbwpAqyARICs+GiOAAAKnCZgfp3rzv9s0esF6md+p6tm8pv55e7wiw0LQQqDUBJi/KQCtwkSArPhojAACCJwkkJvv0nMfr9Xsn3Y6//2Oixpq+PVtFRzESl+iUroCzN8UgFaJIkBWfDRGAAEEigTSTuQ6L3f+fvMhmcW9z1zbRnf2aMxKXzJSJgLM3xSAVsEiQFZ8NEYAAQQcgV1HMjV42jJtPpChyiFBevXWOF3ZpjY6CJSZAPM3BaBVuAiQFR+NEUAAASXtOKqhM5br8PEc1YkM05uDOqtd/ShkEChTAeZvCkCrgBEgKz4aI4CAnwt8sjJFj85dqZw8l9rWi3RW+taJCvNzFYZfHgLM3xSAVjkjQFZ8NEYAAT8VMCt9//HNZr3y702OwBWta2vCLZ1UpVKwn4ow7PIWYP6mALTKHAGy4qMxAgj4oUB2Xr6e+HC15q3Y44z+7p4X6ImrWysokJ9188M4VNiQmb8pAK3CR4Cs+GiMAAJ+JnDkeI7umblcy7YfdQq+kb3b6bauDf1MgeF6ggDzNwWgVQ4JkBUfjRFAwI8EthzM0J3TlmnH4UxFVArW63fEq2fzWn4kwFA9SYD5mwLQKo8EyIqPxggg4CcCS7Yc0r0zk3QsK08NqlfW24ld1Lx2hJ+MnmF6ogDzNwWgVS4JkBUfjRFAwA8E3l++S099tFp5rgLFN6ymyQM7q2bVSn4wcoboyQLM3xSAVvkkQFZ8NEYAAR8WcLkKNParjXrjuy3OKK/rUFd/v7GjwkKCfHjUDM1bBJi/KQCtskqArPhojAACPipwIidfj7yfrAVr9jkjfPB3zfTwFS0UyEpfH73i3jcs5m8KQKvUEiArPhojgIAPChxIz9Ld05dr5e40hQQF6G/9O6hffAMfHClD8mYB5m8KQKv8EiArPhojgICPCWzYd0xDpi3XntQTqhYeokl3JKhrkxo+NkqG4wsCzN8UgFY5JkBWfDRGAAEfEvh24wE9MGuFMrLz1KRmFb2V2EWNa1bxoREyFF8SYP6mALTKMwGy4qMxAgj4iMCMH7Zr+Cdr5SqQLmoSrYl3JKhaeKiPjI5h+KIA8zcFoFWuCZAVH40RQMDLBfJdBRr56TpNW7LdGcmNCQ00qm97hQYHevnI6L6vCzB/UwBaZZwAWfHRGAEEvFjAPOp9cPYKfbPhgDOKx65qqfsubaqAAH7T14svq990nfmbAtAq7ATIio/GCCDgpQIpqSc0ZPpyrd97TJWCAzXu5k66pn1dLx0N3fZHAeZvCkCr3BMgKz4aI4CAFwqs2p3qFH8H07OdX/R4c1BndYqt5oUjocv+LMD8TQFolX8CZMVHYwQQ8DKBL9bs08NzVigr16WWtSM0NbGzGlQP97JR0F0EJOZvCkCrzwEBsuKjMQIIeIlAQUGBJi/aqhe/2KCCAunSFrX02m1xiggL8ZIR0E0EThZg/qYAtPpMECArPhojgIAXCOTmu/Ts/DV6b9kup7cDLmqk/7u+jYKDWOnrBZePLp5FgPmbAtDqw0GArPhojAACHi6QlpmrP81K0uLNh2V+xvfZ69pocI8LPLzXdA+B4gWYvykAi0/JOfYgQFZ8NEYAAQ8W2Hk4U4On/aQtB48rPDRI/7g1Tpe3ru3BPaZrCLgvwPxNAeh+Ws6wJwGy4qMxAgh4qMDy7Uc0dGaSjhzPUd2oME0d1EVt6kV6aG/pFgLnL8D8TQF4/qn5TQsCZMVHYwQQ8ECBj5P36K9zVykn36X29aOc17zUjgzzwJ7SJQRKLsD8TQFY8vSIZeRWeDRGAAGPEjArfSf85xeN//oXp1+/b1Nb42/ppPDQYI/qJ51BoDQEKAC9pABctGiRxo4dq6SkJO3du1fz5s1Tnz59zpqBjz76SG+88YaSk5OVnZ2ttm3bavjw4frDH/5Q1Mb83yNGjDjpGLVr19a+ffvczhYBcpuKHRFAwIMFsnLz9cSHqzQ/OcXp5dBLmuiJq1op0Kz8YEPABwWYv72kAFywYIEWL16s+Ph49e/fv9gC8OGHH1a9evXUq1cvVatWTW+//bb+/ve/68cff1RcXJwTZVMAfvDBB/r666+Loh0UFKRatWq5HXUC5DYVOyKAgIcKmO/5DZ2xXMt3HFVwYIBG9mmnWy9s6KG9pVsIlI4A87eXFIC/vdzmh8aLuwN4pniYu4A333yznnvuuaICcP78+c5dwpJuBKikcrRDAAFPENh8IEN3TlumnUcyFREWrDduT9DFzWt6QtfoAwJlKsD87ScFoMvlUuPGjfXYY4/pz3/+c1EBaB4rR0VFqVKlSuratatGjx6tJk2anDV05nGy+VO4mQDFxsYqLS1NkZGskCvTTysHRwCBUhVYsvmQ7n0nScey8hQbXVlvJ3ZRs5iIUj0HB0PAUwUoAP2kADSF3osvvqj169crJibGyaN5rJyZmakWLVpo//79euGFF7RhwwatXbtWNWrUOGNmz/S9QbMjBaCnfsTpFwIInElgzrKdenreGuW5CpTQqLomD0hQjaqVwELAbwQoAP2gAJw9e7buuusuffzxx7riiivOGu7jx4+radOmzl3CRx555Iz7cQfQb/5tYKAI+KSAy1Wgl77cqIkLtzjj+2PHenrphg4KCwnyyfEyKATOJkAB6OMF4Jw5czR48GDNnTtX1157bbGfhCuvvFLNmjVzVhC7sxEgd5TYBwEEPEHgRE6+hs1J1hdrf33TwYOXN9ewK5rLfK+aDQF/E2D+9uEC0Nz5u/POO2X+91yvjCkMvbm7Z+4ADh06tGihSHEfCAJUnBB/jwACniBw4FiW7pqxXKt2pyk0KNC569cnrr4ndI0+IFAhAszfXlIAZmRkaPPmzU5IzGtcXnnlFecVL9HR0WrYsKGefPJJ7dmzRzNmzHD2MUXfwIEDNWHCBPXr168oXJUrV3YWfZjt0Ucf1fXXX++0P3DggPMdwIULF2r16tVq1KiRW4EkQG4xsRMCCFSgwLqUY7pr+jKlpGWpeniIJg/srC6NoyuwR5wagYoXYP72kgLwu+++cwq+U7dBgwZp2rRpSkxM1Pbt22X2M9tll13mFHNn29/891tuuUXmBdOHDh1y3v130UUXaeTIkWrTpo3bySRAblOxIwIIVIDAtxsO6M+zftbxnHw1qVXFWenbqEaVCugJp0TAswSYv72kAPSs2Pz/3hAgT70y9AsBBKYv2a4R/1orV4HUrUkNTbwjQVHhIcAggAA/5epkIKDA/AAkW4kEKABLxEYjBBAoQ4G8fJdGfrpO03/Y4Zzl5s6xzq97hAYHluFZOTQC3iXA/E0BaJVYAmTFR2MEEChlgfSsXD0we4W+23jQOfLjV7XSvZc2YaVvKTtzOO8XYP6mALRKMQGy4qMxAgiUosCe1BMaMm2ZNuxLV1hIoMbd1ElXt69bimfgUAj4jgDzNwWgVZoJkBUfjRFAoJQEVu5K1ZDpy3UoI1u1IirpzYGd1TG2WikdncMg4HsCzN8UgFapJkBWfDRGAIFSEFiweq+GvZ+srFyXWtWJ0NTELqpfrXIpHJlDIOC7AszfFIBW6SZAVnw0RgABCwGzfm/iwq362xcbnKNc1rKW/nFrnCLCWOlrwUpTPxFg/qYAtIo6AbLiozECCJRQICfPpWfnr9Gc5bucIwzq1kjPXtdGwUGs9C0hKc38TID5mwLQKvIEyIqPxgggUAKBtMxc3ftOkn7YeliBAdJz17VRYo8LSnAkmiDgvwLM3xSAVuknQFZ8NEYAgfMU2HH4uAZPW6atB4+rSmiQ/nFbnH7XqvZ5HoXdEUCA+ZsC0OpTQICs+GiMAALnIbBs+xENnbFcRzNzVTcqTFMHdVGbepHncQR2RQCBQgHmbwpAq08DAbLiozECCLgpMG/Fbj3+wWrl5LvUvn6Upg7qrJjIMDdbsxsCCJwqwPxNAWj1qSBAVnw0RgCBYgTMSt/xX/+iCf/5xdnzD21ra9zNnRQeGowdAghYCDB/UwBaxEciQFZ8NEYAgXMIZOXm67EPVumTlSnOXvdc2kSP/6GVAs3KDzYEELASYP6mACRAVgI0RgCBshA4nJGtoTOTlLTjqIIDAzSqbzvd3KVhWZyKYyLglwIUgBSAVsEnQFZ8NEYAgTMIbD6Q7qz03XXkhCLDgjXxjgR1b1YTKwQQKEUB5m8KQKs4ESArPhojgMApAos3H3Le8ZeelaeG0eF6K7GLmsVUxQkBBEpZgPmbAtAqUgTIio/GCCDwG4H3ftqpZ+avUZ6rQJ0bVdfkgZ0VXSUUIwQQKAMB5m8KQKtYESArPhojgIAkl6vA+T3fSYu2Oh69O9XT3/p3UFhIED4IIFBGAszfFIBW0SJAVnw0RsDvBTJz8jRsTrK+XLvfsRh2RQs9eHkzBQSw0tfvwwFAmQowf1MAWgWMAFnx0RgBvxbYfyxLd01frtV70hQaFKixN3ZQ7071/dqEwSNQXgLM3xSAVlkjQFZ8NEbAbwXWpRzTkOnLtDcty/me3+QBCercONpvPRg4AuUtwPxNAWiVOQJkxUdjBPxS4JsN+/XArBU6npOvprWq6O3EC9WwRrhfWjBoBCpKgPmbAtAqewTIio/GCPiVgPlZt2lLtmvkp+vkKpB6NKuh129PUFTlEL9yYLAIeIIA8zcFoFUOCZAVH40R8BuBvHyXnv90nWb8sMMZ8y1dYjWyTzuFBAX6jQEDRcCTBJi/KQCt8kiArPhojIBfCKRn5erPs1Zo4aaDMot7n7iqlYZe0oSVvn5x9Rmkpwowf1MAWmWTAFnx0RgBnxfYfTRTQ6Yt18b96QoLCdT4m+N0Vbs6Pj9uBoiApwswf1MAWmWUAFnx0RgBnxZI3pXqvOblUEa2akVU0tRBndWhQTWfHjODQ8BbBJi/KQCtskqArPhojIDPCny+eq/zgufsPJda1YlwftO3XrXKPjteBoaAtwkwf1MAWmWWAFnx0RgBnxMwK31f/26Lxn650Rlbr5a19I/b4lW1UrDPjZUBIeDNAszfFIBW+SVAVnw0RsCnBHLyXHp63mrNTdrtjCuxe2M9c21rBbPS16euM4PxDQHmbwpAqyQTICs+GiPgMwKpmTm6950kLd16RIEB0v9d31aDujf2mfExEAR8TYD5mwLQKtMEyIqPxgj4hMD2Q8d157Rl2nrouKqEBum12+PVq2WMT4yNQSDgqwLM3xSAVtkmQFZ8NEbA6wV+2nZEQ2cuV2pmrupFhWlqYhe1rhvp9eNiAAj4ugDzNwWgVcYJkBUfjRHwaoGPft6txz9cpdz8AnVsEKUpgzorJiLMq8dE5xHwFwHmbwpAq6wTICs+GiPglQJmpe+4f2/Sq99sdvp/dbs6euWmTqocGuSV46HTCPijAPM3BaBV7gmQFR+NEfA6gazcfP31g1X618oUp+/3XdZUf/19SwWalR9sCCDgNQLM3xSAVmElQFZ8NEbAqwTML3oMnbFcP+9MVXBggEb3ba+busR61RjoLAII/CrA/O0lBeCiRYs0duxYJSUlae/evZo3b5769OlzzhwvXLhQjzzyiNauXat69erpscce07333ntSm9dff905rjlm27ZtNX78ePXs2dPtzwcBcpuKHRHwaoFf9qdr8LRl2n30hCLDgjVxQIK6N63p1WOi8wj4swDzt5cUgAsWLNDixYsVHx+v/v37F1sAbtu2Te3atdPdd9+te+65x2n7pz/9SbNnz3bam23OnDkaMGCATBHYo0cPTZo0SW+++abWrVunhg0buvW5IEBuMbETAl4t8P0vh3TfO0lKz85Toxrhzs+6Na1V1avHROcR8HcB5m8vKQB/G9SAgIBiC8DHH39cn3zyidavX1/U1Nz9W7lypX744Qfnv3Xt2tUpKN94442ifVq3bu3cWRwzZoxbnw0C5BYTOyHgtQKzftypZz9eo3xXgbo0rq5JAzorukqo146HjiOAwK8CzN8+WgBecskliouL04QJE4qybh4b33TTTcrMzJRZxRceHq65c+eqb9++Rfs89NBDSk5Olnl8fKYtOztb5k/hZgIUGxurtLQ0RUby7i/+YUHAVwRMwffigvWa8t9tzpD6xtXXi/3bq1IwK3195RozDv8WoAD00QKwRYsWSkxM1FNPPVWU8CVLljiPelNSUpwCsH79+s6j4e7duxftM3r0aE2fPl0bN/76Q+6nbsOHD9eIESNO++8UgP79Dwmj9y2BzJw8PfResv69br8zsEeubKEHftdM5ukDGwII+IYABaAPF4CDBw/Wk08+WZRUU+xdfPHFzoIPl8vlFICmKOzWrVvRPqNGjdLMmTO1YcOGMyacO4C+8cFnFAicTWD/sSwNmb5Ma/YcU2hwoMbe0EG9O9UHDAEEfEyAAtBHC8CyegR8av4JkI/9i8Bw/FpgbUqahkxbrn3HslSjSqgmD0xQQqNovzZh8Aj4qgDzt48WgGYRyL/+9S9nRW/hdt999znf7/vtIpCEhARnFXDh1qZNG/Xu3ZtFIL76iWdcCJxF4Ot1+/XgeyuUmZOvZjFV9dagLmpYIxwvBBDwUQEKQC8pADMyMrR5868/u2QWd7zyyivq1auXoqOjnVe2mEe9e/bs0YwZM5x9Cl8DY14BY14FY4o+swr4TK+BmThxovMYePLkyZoyZYrz3sBGjRq5FXkC5BYTOyHgsQLm+8BvLd6uFz5bp4IC6eJmNfXP2+MVVTnEY/tMxxBAwF6A+dtLCsDvvvvOKfhO3QYNGqRp06Y5Cz62b98us1/hZlbyDhs2rOhF0Oau4JleBP3SSy853ws07w0cN26czONjdzcC5K4U+yHgeQJ5+S6N+Nc6zVy6w+ncrRfG6vne7RQSFOh5naVHCCBQqgLM315SAJbqVS/FgxGgUsTkUAiUo8CxrFz9edYKLdp0UGZx71NXt9ZdPS9gpW85XgNOhUBFCjB/UwBa5Y8AWfHRGIEKEdh1JNNZ6btpf4YqhwRp/C2d9Ie2dSqkL5wUAQQqRoD5mwLQKnkEyIqPxgiUu8CKnUd194zlOpSRo5iISpo6qIvaN4gq935wQgQQqFgB5m8KQKsEEiArPhojUK4Cn63aq0feT1Z2nkut60bqrcTOqhtVuVz7wMkQQMAzBJi/KQCtkkiArPhojEC5CJiVvq9/t0Vjv/z1F34ubxWjV2+NU5VKweVyfk6CAAKeJ8D8TQFolUoCZMVHYwTKXCAnz6UnP1qtD3/e7Zzrzh4X6OlrWysokJ91K3N8ToCABwswf1MAWsWTAFnx0RiBMhVIzczRPTOT9OO2I07BN/z6NhrQrXGZnpODI4CAdwgwf1MAWiWVAFnx0RiBMhPYdui47py2TOZ/q1YK1mu3xemyljFldj4OjAAC3iXA/E0BaJVYAmTFR2MEykRg6dbDuvedJKVm5qp+tcqamthZrepElsm5OCgCCHinAPM3BaBVcgmQFR+NESh1gQ+TduuJj1YpN79AHWOracrABMVEhJX6eTggAgh4twDzNwWgVYIJkBUfjREoNQGXq0Cv/HuTXvv2198Mv7Z9Xb18U0eFhQSV2jk4EAII+I4A8zcFoFWaCZAVH40RKBWBrNx8PTp3pT5dtdc53v29muovV7ZUICt9S8WXgyDgiwLM3xSAVrkmQFZ8NEbAWuBgeraGzlyuFTtTFRwYoNH92uumzrHWx+UACCDg2wLM3xSAVgknQFZ8NEbASmDT/nQNfnuZ9qSeUFTlEE28I0HdmtawOiaNEUDAPwSYvykArZJOgKz4aIxAiQUWbTqo+9/9WenZeWpcI1xvJXZRk1pVS3w8GiKAgH8JMH9TAFolngBZ8dEYgRIJvLN0h/7vk7XKdxXowsbRmjggQdFVQkt0LBohgIB/CjB/UwBaJZ8AWfHRGIHzEjAF3+jP12vq99ucdv3i6mtM//aqFMxK3/OCZGcEEBDzNwWg1ceAAFnx0RgBtwWOZ+fpofeS9fX6/U6bR3/fQvf3aqaAAH7T121EdkQAgSIB5m8KQKuPAwGy4qMxAm4J7EvL0pDpy7Q25ZhCgwP18o0ddX3Hem61ZScEEEDgTALM3xSAVp8MAmTFR2MEihVYsyfNKf72H8tWjSqhmjywsxIaVS+2HTsggAAC5xJg/qYAtPqEECArPhojcE6Bf6/brwdnr9CJ3Hw1j6nqrPSNjQ5HDQEEELAWYP6mALQKEQGy4qMxAmcUKCgocBZ6jPp8vQoKpJ7Na+qft8crMiwEMQQQQKBUBJi/KQCtgkSArPhojMBpArn5Lg3/ZK3e/XGn83e3dW2oEX9sq5CgQLQQQACBUhNg/qYAtAoTAbLiozECJwkcy8p1Xu78318OySzuffqa1hpy8QWs9CUnCCBQ6gLM3xSAVqEiQFZ8NEagSGDXkUzdOW2ZfjmQocohQZpwSyf9vm0dhBBAAIEyEWD+pgC0ChYBsuKjMQKOwM87j2rojOU6lJGj2pGVNHVQF7WrH4UOAgggUGYCzN8UgFbhIkBWfDRGQJ+uStEj769UTp5LbetFOsVfnagwZBBAAIEyFWD+pgC0ChgBsuKjsR8LmJW+//x2s/7+1SZH4YrWMZpwS5yqVAr2YxWGjgAC5SXA/E0BaJU1AmTFR2M/FcjOy9eTH63WRz/vcQTMQo+nrmmtoEB+1s1PI8GwESh3AeZvCkCr0BEgKz4a+6HA0eM5uuedJP207YhT8A3/Y1sNuKiRH0owZAQQqEgB5m8KQKv8ESArPhr7mcDWgxkaMn25th06rohKwXrt9nhd2qKWnykwXAQQ8AQB5m8KQKscEiArPhr7kcDSrYd1z8wkpZ3IVf1qlfX24C5qUTvCjwQYKgIIeJIA8zcFoFUeCZAVH439RGDu8l16at5q5eYXqFNsNU0Z2Fm1Iir5yegZJgIIeKIA8zcFoFUuCZAVH419XMDlKtDL/96of367xRnptR3q6uUbOyosJMjHR87wEEDA0wWYvykArTJKgKz4aOzDAlm5+frL+yv12eq9zij/3KuZHrmyhQJZ6evDV52hIeA9AszfFIBWaSVAVnw09lGBg+nZunvGciXvSlVIUIDG9OugGxIa+OhoGRYCCHijAPM3BaBVbgmQFR+NfVBg47505zd996SeULXwEE28I0EXNanhgyNlSAgg4M0CzN8UgFb5JUBWfDT2MYGFmw7q/nd/VkZ2ni6oWUVvJXZx/pcNAQQQ8DQB5m8vKgBff/11jR07Vnv37lXbtm01fvx49ezZ84yZuuyyy7Rw4cLT/u6aa67RZ5995vz3xMRETZ8+/aR9unbtqqVLl7qdUwLkNhU7+rjAzKU7NPyTtcp3FejCC6I16Y4EVa8S6uOjZngIIOCtAszfXlIAzpkzRwMGDJApAnv06KFJkybpzTff1Lp169SwYcPT8nfkyBHl5OQU/ffDhw+rY8eOThtT+BUWgPv379fbb79dtF9oaKiio6PdzjMBcpuKHX1UwBR8L3y2Tm8v3u6MsF98fb3Yr4NCgwN9dMQMCwEEfEGA+dtLh1/RcwAAIABJREFUCkBzZy4+Pl5vvPFGUe5at26tPn36aMyYMcVm0dwtfO6555y7h1Wq/PpIyhSCqampmj9/frHtz7YDASoxHQ19QMA86n1o9gr9Z8MBZzR//UNL/emypgoI4Dd9feDyMgQEfFqA+dsLCkBzJy88PFxz585V3759iwL50EMPKTk5+YyPek9Nbfv27dWtWzdNnjy56K9MAWiKP3PXr1q1arr00ks1atQoxcTEnDX02dnZMn8KNxOg2NhYpaWlKTIy0qc/LAwOgd8K7E07oTunLdf6vcdUKThQL9/UUdd1qAcSAggg4BUCFIBeUACmpKSofv36Wrx4sbp3714UrNGjRzvf4du4ceM5w/bTTz/J3EH88ccfdeGFFxbtax4rV61aVY0aNdK2bdv07LPPKi8vT0lJSapU6cy/UjB8+HCNGDHitPNRAHrF551OlpLA6t1pGjJ9mQ6kZ6tm1VBNHthZ8Q2rl9LROQwCCCBQ9gIUgF5UAC5ZssS5i1e4mbt1M2fO1IYNG86ZlHvuuUem7erVq8+5n3k8bIrB9957T/369TvjvtwBLPsPJWfwbIEv1+7Tw+8l60RuvlrUrqqpg7ooNjrcsztN7xBAAIFTBCgAvaAAtHkEnJmZqbp16+r555+XeWRc3Na8eXPdddddevzxx4vb1fl7AuQWEzv5gEBBQYGm/HerxizYoIICqWfzmvrn7fGKDAvxgdExBAQQ8DcB5m8vKABNKM0j3ISEBGcVcOHWpk0b9e7d+5yLQKZNm6Z7771Xe/bsUY0a534ZrVkpbB41m+8JDhw40K3PAgFyi4mdvFwgN9+l5z5eq9k/7XRGcnvXhhrxx7YKDmKlr5dfWrqPgN8KMH97SQFY+BqYiRMnFi3mmDJlitauXes8tjUFmyneTl0RbN4TaP67eaz72y0jI0Pm+3z9+/d37hBu375dTz31lHbu3Kn169crIiLCrQ8FAXKLiZ28WCDtRK7zcufvNx+SWdz7zLVtdGePxqz09eJrStcRQIAneCYDAQXm2Y4XbObu30svveS8yqVdu3YaN26cLrnkEqfn5sXPjRs3lrnjV7ht2rRJLVu21FdffaUrr7zypBGeOHHCeYXMihUrnFfBmCKwV69eGjlypLOq192NAtBdKfbzRoGdhzN15/Rl2nwgQ+GhQZpwS5yubFPbG4dCnxFAAIGTBJi/vagA9MTsEiBPvCr0qTQEknYc0d0zknTkeI7qRIbpzUGd1a5+VGkcmmMggAACFS7A/E0BaBVCAmTFR2MPFfg4eY/++sEq5eS51LZepLPSt05UmIf2lm4hgAAC5y/A/E0BeP6p+U0LAmTFR2MPEzDfBnn1P5s17utNTs/M494Jt3RSeGiwh/WU7iCAAAJ2AszfFIBWCSJAVnw09iCB7Lx8PfHhas1bscfp1d09L9ATV7dWUCA/6+ZBl4muIIBAKQkwf1MAWkWJAFnx0dhDBMz3/O6ZuVzLth91Cr6Rvdvptq4NPaR3dAMBBBAofQHmbwpAq1QRICs+GnuAwJaDGbpz2jLtOJypiLBgvX57vHo2r+UBPaMLCCCAQNkJMH9TAFqliwBZ8dG4ggWWbD6ke99J0rGsPMVGV9Zbg7qoeW333oFZwV3n9AgggICVAPM3BSABshKgsbcKvL9sl56at1p5rgLFN6ymyQM7q2bVSt46HPqNAAIInJcABSAF4HkF5tSdCZAVH40rQMDlKtBLX27UxIVbnLNf37Gext7QQWEhQRXQG06JAAIIVIwA8zcFoFXyCJAVH43LWeBETr4eeT9ZC9bsc8784OXNNeyK5vysWzlfB06HAAIVL8D8TQFolUICZMVH43IUOHAsS3fPWK6Vu9MUGhSoF/u3V7/4BuXYA06FAAIIeI4A8zcFoFUaCZAVH43LSWDDvmO68+1lSknLUvXwEE0a0FkXXhBdTmfnNAgggIDnCTB/UwBapZIAWfHRuBwEvt14QA/MWqGM7Dw1qVlFbyV2UeOaVcrhzJwCAQQQ8FwB5m8KQKt0EiArPhqXscCMH7Zr+Cdr5SqQujWpoTfuiFe18NAyPiuHRwABBDxfgPmbAtAqpQTIio/GZSSQ7yrQyE/XadqS7c4ZbkxooFF92ys0OLCMzshhEUAAAe8SYP6mALRKLAGy4qNxGQiYR70Pzl6hbzYccI7+2FUtdd+lTVnpWwbWHBIBBLxXgPmbAtAqvQTIio/GpSyQknrC+Vm3DfvSVSk4UONu7qRr2tct5bNwOAQQQMD7BZi/KQCtUkyArPhoXIoCq3an6q7py3UgPdv5RY83B3VWp9hqpXgGDoUAAgj4jgDzNwWgVZoJkBUfjUtJ4Is1+/TwnBXKynWpZe0ITU3srAbVw0vp6BwGAQQQ8D0B5m8KQKtUEyArPhpbChQUFGjyoq168YsNKiiQLm1RS6/dFqeIsBDLI9McAQQQ8G0B5m8KQKuEEyArPhpbCOTmu/Ts/DV6b9ku5ygDuzXSc9e1UXAQK30tWGmKAAJ+IsD8TQFoFXUCZMVH4xIKpGXm6k+zkrR482EFBsgp/BJ7XFDCo9EMAQQQ8D8B5m8KQKvUEyArPhqXQGDH4ePOSt8tB48rPDTIeeT7u1a1S3AkmiCAAAL+K8D8TQFolX4CZMVH4/MUWL79iIbOTNKR4zmqGxWmqYO6qE29yPM8CrsjgAACCDB/UwBafQoIkBUfjc9D4OPkPfrr3FXKyXepff0oTR3UWTGRYedxBHZFAAEEECgUYP6mALT6NBAgKz4auyFgVvpO+M8vGv/1L87ev29TW+Nv6aTw0GA3WrMLAggggMCZBJi/KQCtPhkEyIqPxsUIZOXm6/EPV+nj5BRnz6GXNNETV7VSoFn5wYYAAgggUGIB5m8KwBKHxzQkQFZ8ND6HwOGMbN0zM0nLdxxVcGCARvZpp1svbIgZAggggEApCDB/UwBaxYgAWfHR+CwCmw9kOCt9dx7JVERYsCbekaAezWrihQACCCBQSgLM3xSAVlEiQFZ8ND6DwOLNh3TfO0k6lpWn2OjKejuxi5rFRGCFAAIIIFCKAszfFIBWcSJAVnw0PkXgvZ926pn5a5TnKlBCo+qaPCBBNapWwgkBBBBAoJQFmL8pAK0iRYCs+Gj8PwGXq0B/+3KDJi3c6vyX3p3q6W/9OygsJAgjBBBAAIEyEGD+pgC0ihUBsuKjsaQTOfkaNidZX6zd53g8dHlzPXxFcwUEsNKXgCCAAAJlJcD8TQFolS0CZMXn940PHMvSXTOWa9XuNIUGBeqlGzqoT1x9v3cBAAEEEChrAeZvCkCrjBEgKz6/brwu5ZiGTF+mvWlZqh4eoskDO6tL42i/NmHwCCCAQHkJMH9TAFpljQBZ8flt42827NcDs1boeE6+mtSq4qz0bVSjit96MHAEEECgvAWYvykArTJHgKz4/LLxtMXb9Pyn6+QqkLo3raE3bk9QVHiIX1owaAQQQKCiBJi/KQCtskeArPj8qnFevksjP12n6T/scMZ9c+dYvdC3nUKCAv3KgcEigAACniDA/O1FBeDrr7+usWPHau/evWrbtq3Gjx+vnj17njFH06ZN0+DBg0/7uxMnTigsLKzov5/PMc90IgLkCR9jz+9DelauHpi9Qt9tPOh09vGrWuneS5uw0tfzLx09RAABHxVg/vaSAnDOnDkaMGCATMHWo0cPTZo0SW+++abWrVunhg1P/31UUwA+9NBD2rhx40nRrVOnTtH/fb7HpAD00X8FynhYe1JPaMi0ZdqwL11hIYEaf3MnXdWubhmflcMjgAACCJxLgALQSwrArl27Kj4+Xm+88UbR9WzdurX69OmjMWPGnHaNTQH48MMPKzU19azX/3yPSQHIPybnK7ByV6rzmpeD6dmqFVFJbw7srI6x1c73MOyPAAIIIFDKAhSAXlAA5uTkKDw8XHPnzlXfvn2LImDu8CUnJ2vhwoVnLADvuusu1a9fX/n5+erUqZNGjhypuLg4Z9+SHNO0y87Odv4UbiZAsbGxSktLU2RkZCnHk8N5s8Bnq/bqkfeTlZ3nUqs6EZqa2EX1q1X25iHRdwQQQMBnBCgAvaAATElJcQq5xYsXq3v37kXhGz16tKZPn37aY16zw9KlS7V582a1b99e5iJPmDBBn3/+uVauXKnmzZurJMc0xx0+fLhGjBhx2geAAtBn/k2wHkhBQYFe+2azXv73JudYvVrW0qu3xikijJW+1rgcAAEEECglAQpALyoAlyxZom7duhVd+lGjRmnmzJnasGFDsXFwuVzOI+RLLrlEr776alEBeL7H5A5gsdR+vUNWbr6e+HCV5ienOA539rhAT1/bWkGB/KybXweDwSOAgMcJUAB6QQFY0se1p6bt7rvv1u7du7VgwYISPwI+9ZgEyOM+0xXWoQPpWbrvnZ+VtOOoU/A937utbu/aqML6w4kRQAABBM4uwPztBQWguXxmwUZCQoKzCrhwa9OmjXr37n3GRSCnXnLzWO7CCy90Hgm/9dZbzl/bHtMcgwDxz4sRMIs97pmZpH3HshQZFqzXb0/Qxc1rgoMAAggg4KECzN9eUgAWvrJl4sSJzmPgyZMna8qUKVq7dq0aNWqkgQMHOt8TLFwRbL6nd9FFFznf9zMX2Tz2NY+LzfcITSFotuKO6U5mCZA7Sr69z4dJu/XkvNXKyXOpaa0qmjKws5rUqurbg2Z0CCCAgJcLMH97SQFocmbu/r300kvOi6DbtWuncePGOd/pM9tll12mxo0by7z+xWzDhg3TRx99pH379ikqKspZ/WsWcPz2O4TFHdOdbBMgd5R8cx/zyx5jFmzQ1O+3OQO8onWMxt3cicUevnm5GRUCCPiYAPO3FxWAnpg9AuSJV6Xs+3QoI1sPzl6hJVsOOyd74HfNNOyKFgpksUfZ43MGBBBAoBQEmL8pAK1iRICs+LyycdKOI7r/3RXO9/3CQ4P08o0ddXV7ftnDKy8mnUYAAb8VYP6mALQKPwGy4vOqxmYh0bQl2zXqs/XKcxU43/ebNCBBzWIivGocdBYBBBBAgEWcJgMBBWZmYyuRAAVgidi8rlFGdp6e/Gi1/rXy1/f7Xdehrl7s30FVKwV73VjoMAIIIIAABSAFoOWngALQEtALmq/Zk6YHZq/QtkPHFRwY4LzYObF7YwUE8HJnL7h8dBEBBBA4owDzN3cArT4aBMiKz6MbmxvjM37Y4Tzyzcl3qV5UmP5xW5wSGkV7dL/pHAIIIIBA8QLM3xSAxafkHHsQICs+j22clpmrxz5cqS/X7nf6eEXr2vr7jR1ULTzUY/tMxxBAAAEE3Bdg/qYAdD8tZ9iTAFnxeWTjH7Yc1l/eT1ZKWpZCgwL15DWteOTrkVeKTiGAAAIlF2D+pgAseXr4KTgrO09rbH7J4+V/b9TkRVtllkU1rhGuf9war/YNojytq/QHAQQQQMBSgAKQAtAqQgTIis9jGm8+kK4HZydr3d5jTp9u6RKrZ69royqs8vWYa0RHEEAAgdIUYP6mALTKEwGy4qvwxi5Xgd5esl0vfbFB2XkuVQ8PcV7v8oe2dSq8b3QAAQQQQKDsBJi/KQCt0kWArPgqtPH2Q8f12Aer9NP2I04/LmlRS3+/oYNiIsMqtF+cHAEEEECg7AWYvykArVJGgKz4KqSxues344ftevGLDcrKdalKaJCeura1bruwIe/2q5ArwkkRQACB8hdg/qYAtEodAbLiK/fGWw9mOL/o8eO2X+/6dW9aQ3/r30Gx0eHl3hdOiAACCCBQcQLM3xSAVukjQFZ85dbYrPCdvGiLXv1ms8z/u3JIkJ66ppVu79pIgYH8oke5XQhOhAACCHiIAPM3BaBVFAmQFV+5NP5551E9+eFqbdyf7pzv0ha19EKfdtz1Kxd9ToIAAgh4pgDzNwWgVTIJkBVfmTZOzczR2C83atZPO533+kVXCdX/Xd9Gf+xYj+/6lak8B0cAAQQ8X4D5mwLQKqUEyIqvTBqbRR4fJO12FnkcOZ7jnKNffH09c20bpwhkQwABBBBAgPmbAtDqU0CArPhKvfGaPWl69uM1WrEz1Tl2i9pV9XzvdrqoSY1SPxcHRAABBBDwXgHmbwpAq/QSICu+Umt8ID1LL3+5Se8n7XIe95pXuwy7soUGdW+skKDAUjsPB0IAAQQQ8A0B5m8KQKskEyArPuvGWbn5mvr9Nr3+7WYdz8l3jme+4/f0ta1Vmxc6W/tyAAQQQMBXBZi/KQCtsk2ArPhK3Nh8z++TlSnOIo89qSec43SKreb8fm9Co+olPi4NEUAAAQT8Q4D5mwLQKukEyIrvvBsXFBTou40H9bcvNmjDvl9f61I3KkyPX9XKufPHO/3Om5QGCCCAgF8KMH9TAFoFnwBZ8Z1X46QdR53C76f//YpHRKVg3XNpEw25uIkqhwad17HYGQEEEEDAvwWYvykArT4BBMiKz63GpvCb8J9ftGjTQWf/0OBAJXZvrPsubarqvNbFLUN2QgABBBA4WYD5mwLQ6jNBgKz4ztn41MIvKDBAN8Q30ENXNFe9apXL7sQcGQEEEEDA5wWYvykArUJOgKz4TmtsvuP3/eZDmrhwixZvPuz8vSn8+sfX1597NVfDGuGle0KOhgACCCDglwLM3xSAVsEnQFZ8RY3z8l1asGafU/itTTlWVPiZO37392pG4Vc6zBwFAQQQQOB/AszfFIBWHwYCZMWnY1m5mrt8t6Yv2a6dRzKdg1UOCdLNXWJ1V88L1KA6d/zshGmNAAIIIHAmAeZvCkCrTwYBKhnf5gMZmvHDduc3ezP/9wLn6uEhzi93DOrWmMUdJWOlFQIIIICAmwLM3xSAbkblzLsRIPf5cvJc+mrdPr330y7ne36Fm/m93sTuF6hPXD2Fhwa7f0D2RAABBBBAoIQCzN8UgCWMzq/NCFDxfFsPZui9Zbv0YdJuHT6e4zQICJCuaF1bg7s3VremNRRg/gMbAggggAAC5STA/E0BaBU1AnRmviPHc/TpqhTNW7FHK3amFu1UO7KSbuoc6/yJjeb7fVbhozECCCCAQIkFmL8pAEscHu4AnkyXkZ2nbzYc0CfJe5yfa8tzFTg7BAZIl7WM0a0XNlSvlrUUHBRoZU5jBBBAAAEEbAUoACkArTLk7wEyq3j/s36/Pl+9Tws3HZT5nl/h1q5+pPp0qq8/dqqnmIgwK2caI4AAAgggUJoC/j5/G8uAAvP2XbYSCfhjgMx3+sydPnOX78dth5Wb///j07hGuK5pX1d94+qree2IEpnSCAEEEEAAgbIW8Mf5+1RTCkCLlPlDgNIyc7V022H9sOWwvtt4QNsP//q+vsKteUxVXd2+rq5uV0et6kSwoMMiTzRFAAEEECgfAX+Yv4uTpAAsTugcf++LATqcka2fd6Zq+fYjWrLlsNakpOm394hDggJ04QXR6tUyRr9rFaMmtapaCNIUAQQQQACB8hfwxfn7fBW9pgB8/fXXNXbsWO3du1dt27bV+PHj1bNnzzOOd8qUKZoxY4bWrFnj/H1CQoJGjx6tCy+8sGj/xMRETZ8+/aT2Xbt21dKlS9029PYAHc/O04Z96VqXkuas1v1559HT7vAZjCa1qqh70xq6uFlNXdy8lqpW4n19boeEHRFAAAEEPE7A2+fv0gD1igJwzpw5GjBggEwR2KNHD02aNElvvvmm1q1bp4YNG57mcPvttzv7de/eXWFhYXrppZf00Ucfae3atapfv76zvykA9+/fr7fffruofWhoqKKjo9129ZYAZeXma9uh49pyMENbDx7Xpv2m6DumbYePn3R3r3DgzWKqKr5hNecdfd2a1FSdKBZxuB0KdkQAAQQQ8HgBb5m/yxLSKwpAc2cuPj5eb7zxRpFF69at1adPH40ZM6ZYn/z8fFWvXl2vvfaaBg4cWFQApqamav78+cW2P9sOnhAgU9wdysiWeffe4Ywc7T+WpT2pJ7Tn6Ant/t//pqSdOGOhZ8YVE1FJbetFqn2Dak7RFxdbXVHhISU2oSECCCCAAAKeLuAJ83dFG3l8AZiTk6Pw8HDNnTtXffv2LfJ66KGHlJycrIULFxZrmJ6erpiYGOcY1113XVEBaIo/c9evWrVquvTSSzVq1Chnv7Nt2dnZMn8KNxOg2NhYpaWlKTIysth+uLvDgtV79cXafc679PLyXco3/+sqkCn2jmebP3ky791Lz8rTidx8tw4bGRaspjFV1bTWr3/a1ItUm7qRqhVRya327IQAAggggICvCFAAesFrYFJSUpzHtosXL3Ye6RZu5jt95jt8GzduLDaP999/v7788kvnO4HmkbDZzGPlqlX/X3tnAitFsYXhAyhXBPQCbiwKLrgg4oYKLgiJxj0oGNe4465xiZGIIiCoqChiXBCNoihi3DXuPIMbLgmicQFBZRVXRCOKGoSXv15q3jD3zu3p6b7T3XO/Sm5Gma7qOt+prvq76lRNG+vatastWLDAhg8fbqtXr7ZZs2ZZTU39omjkyJE2atSoOveLWwCOf32eTfjP/EC7/AUtWzS3Tdq0tA5tatxnp9pW1rldK+usz9pW1m2T1tahdUt26JZMlAshAAEIQKCaCSAAMyQAZ86caX379s21R83WTZkyxebOndtgG1X839ixY23GjBnWq1evotdqc4nE4LRp02zQoEH1XlepGcBZi1bY7MUrbL3mzdwvZ+izRfNmVrN+C2tTo7/1rbX7XM/at27pPvk93WruqrANAhCAAATiJIAAzIAAjLIEPG7cOBszZoxNnz7devfuHdh2unfvbkOGDLGhQ4cGXqsLaEAlYeIiCEAAAhCAQKoIMH5nQACqxWgTiI5y0S5gn3r06GEDBw4suglER8ZI/Gnpt0+fPoENb/ny5W6pedKkSbmNIkGZaEBBhPgeAhCAAAQgkD4CjN8ZEYD+GJiJEye6ZWCJNJ31p2NdtGyrnb0Sb35HsJZ9FdM3depUdxyMT4r509/KlStN8XyDBw+2jh072sKFC23YsGG2ePFimzNnjrVtW9rPmNGA0vdQUyMIQAACEIBAEAHG74wIQDlSs38SdorV69mzp40fP9769evnfNy/f3/r1q2bTZ482f2//nvRokV1/D9ixAgn/FatWuWOkJk9e7bpKBiJwAEDBtjo0aPdrt5SEw2oVFJcBwEIQAACEEgPAcbvDAnA9DSb/9eEBpRGr1AnCEAAAhCAQMMEGL8RgJGeERpQJHxkhgAEIAABCCRCgPEbARip4dGAIuEjMwQgAAEIQCARAozfCMBIDY8GFAkfmSEAAQhAAAKJEGD8RgBGang0oEj4yAwBCEAAAhBIhADjNwIwUsOjAUXCR2YIQAACEIBAIgQYvxGAkRoeDSgSPjJDAAIQgAAEEiHA+I0AjNTwaECR8JEZAhCAAAQgkAgBxm8EYKSGRwOKhI/MEIAABCAAgUQIMH4jACM1PBpQJHxkhgAEIAABCCRCgPEbARip4f32229WW1trS5YssY022ihSWWSGAAQgAAEIQKAyBCQA9dOv+jnYjTfeuDI3Tdldmq1du3ZtyuqUmeosXbo01G8HZ8YwKgoBCEAAAhBoAgQ0gdOlS5cmYGldExGAEdy+Zs0aW7ZsmbVt29aaNWsWoaS6Wf3bSbXOLmJfrM0lkcLwYSLYY7tptftPoKrdRuwr/3HQ3Nfvv/9unTp1subNm5dfUIZzIgBT6rxqj0/AvpQ2vBDVwochYKXw0mr3nxeAWt5TuE41hulUuw+r3b6kuwUEYNIeKHL/am/42JfShheiWvgwBKwUXlrt/kMAprDRhaxSU2ijIZHEejkCMFac8RVW7Q0f++JrK0mVhA+TIh/PfavdfwjAeNpJkqU0hTaaJF8EYJL0G7j333//bTfeeKNdddVVVlNTk9Jall8t7CufXVpy4sO0eKK8elS7/0Sl2m3EvvLaPrn+RwABSEuAAAQgAAEIQAACTYwAArCJORxzIQABCEAAAhCAAAKQNgABCEAAAhCAAASaGAEEYBNzOOZCAAIQgAAEIAABBCBtAAIQgAAEIAABCDQxAgjACjn87rvvtltuucW+++4723nnne3222+3Aw44oOjdn3rqKRs+fLh9/fXXtu2229r1119vxxxzTO56nWI+atQomzRpkq1YscL22Wcfu+uuu1zZSaQw9t1333328MMP22effeaquueee9oNN9xge++9d67qp59+uj300EPrmCIb33///STMc/cMY+PkyZPtjDPOqFPXVatW2QYbbJD79zBlNrbhYerSv39/e/PNN+tU6fDDD7cXX3zR/XuafPjWW2+552/WrFnuGXzmmWfs6KOPbhCp7Lv88svt888/d78WcOWVV9p55523Tp4wzBrTf2Hte/rpp+2ee+6xjz/+2O2UVb8xcuRIO+SQQ3LV1P+rj8lPm2++uX3//feNaUrRssPaOGPGDBswYECd8ubMmWM77rhj7t+D+tpKGRvWvvqeL9W1R48ers0qpcmHOtVC7W7u3LnWqlUr23fffe2mm26yHXbYoUHEQf5J21hYqfYSx30QgHFQDCjj8ccft1NOOcUJiP3228/uvfdeu//+++2LL76wrbbaqk7u9957z4nD0aNHO9Gnweraa6+1d955xwk9JT04EoUSGttvv72NGTPG1IF8+eWX7qfpKpnC2nfyySc7DuoAJIZuvvlm1zGo0+rcuXNOPPzwww/24IMP5kxp2bKltW/fvpKm5e4V1kb55ZJLLnH+yE9bbLFF2WU2puFh7fvll1/sn3/+yVVp+fLltuuuu7p2rYFJSZ9p8eHLL79s7777ru2xxx42ePDgQAG4YMEC69mzp5199tl27rnnurwXXHCBPfbYYy6/Ulhmjem/sPZdeumlTtRKINXW1rrnbNy4cfbBBx/Y7rvvnhMPTz75pE2fPj1X9RYtWtimm27amKYULTusjV4A6hnM/xUQ1V92KJXS11bK2LD26ddN9ELp0+oHf01KAAAKmUlEQVTVq90zePHFFzvhp6TPtPjw0EMPtRNOOMH22msvU12vvvpq+/TTT9042Lp163oxl+KfNI2FlWorcd0HARgXyQbKkWjTwKM3bp922mknNwOht6LCdPzxx7vfsFSH4JMennbt2rkBSG886rzViQ8dOtRdord4vZ3rYdCAVckU1r7Cuv3777/OtjvvvNNOPfXUnHj49ddf7dlnn62kKUXvFdZGCUD5RzYUS2HLbEwQUeuiGW29pGh2zXfmEoBp8qHnp9/tDpoB1HP1/PPPm2aLfNLs3yeffOJEg1JUZo3lz1Lsq+/emgVU3yM/evGg50+zhGlLpdjoBaBWSCRy60tBfW1SdpdiX2Hd5KtBgwaZXl66du2aeh/+9NNPttlmm7mVhH79+pXln7SNhUm1l3LviwAsl1yJ+TRLsuGGG9oTTzyxzhKuZofUsda3jKZZwcsuu8z9+TR+/Hi3bLxo0SL75ptv3LLwRx99lHtb13UDBw50HV3h0mmJVS3rsnLsK7yRfpBbHYEYHXnkke5riQd1aJr1k00HHnigm/HUdZVO5dgoAThkyBA3oymBu9tuu7kZXT+7Uk6ZjWV3HHXZZZddrG/fvi4kwac0+TCfXSmDqwYk+WrChAm5rBKNxx13nP3555/uJSzsc91Y/isstxT7CvOsWbPGunXr5pa5L7roopx40LK5fktXh9FL8CpUY5tttqmUKUXvU4qNXgDKrr/++sstjV5zzTXrLAsH9bVJGVqKfYV1O+qoo9xEwGuvvZb7SjOAafXhV199Zd27d3ezgJptry8F+SdNY2FSbSXKfRGAUeiVkHfZsmVOBGgJSUuePqkjlVArXCLU9xI9EhAnnXRS7vqpU6e6mDI94DNnznRLqN9++62bCfTpnHPOcQLx1VdfLaFm8VxSjn2Fd77wwgtdnRUT6OPjtLzWpk0b9yarN1rFQ2rZQDFclf5llHJsVKyiOjgJI83mSki89NJLbgZJnV45ZcbjsbqlRK3Lhx9+6MSBlg/z4zjT5MOwAlBhFRKww4YNy2X1z514SQCGfa4by39xCECJhLFjx7oZT/+SpRUIiV2x0FK+wkwUv6VQjQ4dOlTKnHrvU4pAUt+qsBjFGKvfnDJlik2cONEkDP2MU1Bfm5SRpdiXXzfNvG+55ZamcUIvKT6l1Yd6fjRhodnZt99+uyjmIP+kaSxMqq1EuS8CMAq9EvL6wVUNVTMkPmk2Sx2SOtTCpEYvcXjiiSfmvnr00UftrLPOcm+y+QNRx44dc9coXmnJkiX2yiuvlFCzeC4px778Oyv+TwOPOuVevXoVrZQ6OInBadOmuWWOSqaoNqqummFRGIAGnjvuuCMnAMO0i8ayOap9CjmQHXqTbygl6cNyBKBeuPRTjD7pJW7//fd3y9zypwRgGvwXVQAqrESz1c8995wddNBBRV34xx9/uJUHzRJqc0ySKaxA8nXVLJnyanlfKaivTcrGsPYplOjWW291/YpsKpbS4kO99GuzmOLau3TpUrS+Qf5J01iYVFuJcl8EYBR6JeQtZ3ktS9Pe5djnsSnoXLMKCjLv3bt3IE3NnGmg8nGPgRliuiCKjflVkEBfunSpi+2Mq8w4TIxSF80Q6SXkuuuuc5teglJSPgwrAJvKErBmaSV0FX5xxBFHBLnPDj74YNtuu+3WiWcOzNQIF4QVSL4KevF+5JFHcrGdQX1tI1S9pCLD2KfZNM3SKnxGoUJBKWkfapOKwns0O7v11ls3WN0g/7AEHOTthr9HAEbjV1JuLY9pGUK7gH1SPIqmwIttAlFcnJYMfTrssMNcLFz+JhDFCOptXEmDuJZuktoEEsY+1VdLThJ/Wvrt06dPIEftMtWMi2LM/EaRwEwxXhDWh4W3Viet5VEtCT/wwAPu66hlxmhe2XVRqII2RygcIWhZMGkfel6lDK56yXjhhRfcDkWfzj//fBe3m78JJGy7j9NnxcoqxT7lVV9y5plnus+gI3F0vZZRNQOoUBO/UaQS9tR3j1JtLMx77LHHmnawv/HGG+4rbQJpqK/Ngn0+1rGhWDpvR5I+VB8o8adYWtVZL4NBKcg/fhNIWsbCIHvS9j0CsAIe8cdFKP7EB8rrLDzF0mhZU4JG4saLQU1rawZCb6sSiVqaUfBy4TEwul7HN+hBUkyhHqokj4Ep1T4t+yqmT/EqimX0STF/+lu5cqU7vkDHbWh2aeHChS4Wa/Hixe7NvdLH3Kh+YX2o89MkbOUbxQBq2VdL/lpG9HFyQWVWoGnmbhFUl8I26jPquCK1XS3N56e0+VD1UUymkjZ33HbbbW4zgI4V0iyDlnolYnU+pZI/BkbL25q5leiT0K3vGJhi7b6S/gtrn+yQTxWbmh9SofPZtOlD6YorrjAtmYrPjz/+6F7YtGlNQsPvMk2zjdo0pw0g2t2sF2TN/CncROfKeZtL6WsrZWNYH/p66Yix+fPn13tGapp8qGOU1OdrPMs/+0/tTe1OKetjYaXaSlz3QQDGRTKgHM3+Sfgofkg7njRV7wORdaiuOirNpviks5sk+vwUt8RgfkftD7/UmYL5B0EX203V2GaGsU+2arNKYRoxYoQTfjrbSjMSs2fPdseISARqsNYuWgU6J5XC2Kg3Up1tqENz1cFJdMi2/DhQ2dFQmZW2M4x9qtu8efNcR65dh1pWyk9p82GxQ4FPO+0099xpw4deNHSdTxI78qM/CFqzgvUdBF3sua6k/8LaV+wgb89DddeZbVqm+/nnn93Zf3qh0TOo1YskUlgb5RetGEjYS2BICEro67Dy/BTU11bK1rD2qV46C1D9o4S8XlQKU5p8qFnb+pImMfzZodUwFlaqvcRxHwRgHBQpAwIQgAAEIAABCGSIAAIwQ86iqhCAAAQgAAEIQCAOAgjAOChSBgQgAAEIQAACEMgQAQRghpxFVSEAAQhAAAIQgEAcBBCAcVCkDAhAAAIQgAAEIJAhAgjADDmLqkIAAhCAAAQgAIE4CCAA46BIGRCAAAQgAAEIQCBDBBCAGXIWVYUABCAAAQhAAAJxEEAAxkGRMiAAAQhAAAIQgECGCCAAM+QsqgoBCEAAAhCAAATiIIAAjIMiZUAAAhCAAAQgAIEMEUAAZshZVBUCEIAABCAAAQjEQQABGAdFyoAABCAAAQhAAAIZIoAAzJCzqCoEIAABCEAAAhCIgwACMA6KlAEBCEAAAhCAAAQyRAABmCFnUVUIQAACEIAABCAQBwEEYBwUKQMCEIAABCAAAQhkiAACMEPOoqoQgAAEIAABCEAgDgIIwDgoUgYEIAABCEAAAhDIEAEEYIacRVUhAAEIQAACEIBAHAQQgHFQpAwIQAACEIAABCCQIQIIwAw5i6pCAAIQgAAEIACBOAggAOOgSBkQgAAEIAABCEAgQwQQgBlyFlWFAAQgAAEIQAACcRBAAMZBkTIgAAEIQAACEIBAhgggADPkLKoKAQhAAAIQgAAE4iCAAIyDImVAAAIQgAAEIACBDBFAAGbIWVQVAhCAAAQgAAEIxEEAARgHRcqAAAQgAAEIQAACGSKAAMyQs6gqBCAAAQhAAAIQiIMAAjAOipQBAQhAAAIQgAAEMkQAAZghZ1FVCEAAAhCAAAQgEAeB/wI0EhDW9TQpHQAAAABJRU5ErkJggg==\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x9c0d2d5e48>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.linspace(0, 2, 100)\n",
"y = np.where(x <= 0.5, x*x+0.25, x)\n",
"plt.figure()\n",
"plt.plot(x, y, label='limited')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"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",
" fig.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 overridden (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",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAgAElEQVR4XuydB1iW1f/Gb6YIMkRxI7gVcKIoKDhTM0ttp2mOssxytbdWamq5KrflyF2aZWmmKSKguHCguBAXbmUosvlf5/GPv0qNF877vjzjfq6Ly8HzPeNz7pfvzXOec45Nfn5+PniRAAmQAAmQAAmQAAkYhoANDaBhxpodJQESIAESIAESIAGFAA0ghUACJEACJEACJEACBiNAA2iwAWd3SYAESIAESIAESIAGkBogARIgARIgARIgAYMRoAE02ICzuyRAAiRAAiRAAiRAA0gNkAAJkAAJkAAJkIDBCNAAGmzA2V0SIAESIAESIAESoAGkBkiABEiABEiABEjAYARoAA024OwuCZAACZAACZAACdAAUgMkQAIkQAIkQAIkYDACNIAGG3B2lwRIgARIgARIgARoAKkBEiABEiABEiABEjAYARpAgw04u0sCJEACJEACJEACNIDUAAmQAAmQAAmQAAkYjAANoMEGnN0lARIgARIgARIgARpAaoAESIAESIAESIAEDEaABtBgA87ukgAJkAAJkAAJkAANIDVAAiRAAiRAAiRAAgYjQANosAFnd0mABEiABEiABEiABpAaIAESIAESIAESIAGDEaABNNiAs7skQAIkQAIkQAIkQANIDZAACZAACZAACZCAwQjQABpswNldEiABEiABEiABEqABpAZIgARIgARIgARIwGAEaAANNuDsLgmQAAmQAAmQAAnQAFIDJEACJEACJEACJGAwAjSABhtwdpcESIAESIAESIAEaACpARIgARIgARIgARIwGAEaQIMNOLtLAiRAAiRAAiRAAjSA1AAJkAAJkAAJkAAJGIwADaDBBpzdJQESIAESIAESIAEaQGqABEiABEiABEiABAxGgAbQYAPO7pIACZAACZAACZAADSA1QAIkQAIkQAIkQAIGI0ADaLABZ3dJgARIgARIgARIgAaQGiABEiABEiABEiABgxGgATTYgLO7JEACJEACJEACJEADSA2QAAmQAAmQAAmQgMEI0AAabMDZXRIgARIgARIgARKgAaQGSIAESIAESIAESMBgBGgADTbg7C4JkAAJkAAJkAAJ0ABSAyRAAiRAAiRAAiRgMAI0gAYbcHaXBEiABEiABEiABGgAqQESIAESIAESIAES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\" width=\"640\">"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x9c0d31f0f0>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.linspace(0, 2, 100)\n",
"y = np.where(x >= 0.5, x-(x-0.5)*(x-0.5), x)\n",
"plt.figure()\n",
"plt.plot(x, y, label='limited')\n",
"plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}