29549 lines
2.9 MiB
29549 lines
2.9 MiB
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Replot\n",
|
|
"======\n",
|
|
"\n",
|
|
"This is some basic Jupyter notebook to show you the features of [replot](https://github.com/Phyks/replot). It gives you usage examples, and is used by me as a visual test suite to check I did not break anything between updates.\n",
|
|
"\n",
|
|
"For detailed documentations, please refer to the module documentation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Let's go!\n",
|
|
"\n",
|
|
"First import the required modules. Note that importing `replot` will not have any side effect and that if you previously imported `matplotlib` it will be left untouched."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import replot\n",
|
|
"\n",
|
|
"%matplotlib notebook"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Also import numpy as it will be useful…\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"# and add some black magic for easy reloading of the module before executing any cell (just here to ease testing)\n",
|
|
"%load_ext autoreload\n",
|
|
"%autoreload 2\n",
|
|
"\n",
|
|
"# ignore matplotlib warnings about too many figures in the notebook\n",
|
|
"import matplotlib as mpl\n",
|
|
"mpl.rcParams[\"figure.max_open_warning\"] = 40"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Basic plotting\n",
|
|
"\n",
|
|
"Let's start by doing some basic plotting."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Let's plot a basic data series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nO2dCZBUZZque/VOOHbMBuNEwVWoyqqZmCUmZia6bzgz0dExMRMxPXe2a/dVUEH2VTaRfRGFBtoFFQUXRMVutV0ARdwXUFxAUVwQlMzacj8loHbPdM+dVv/7/+dUUYWAlZCZ9Z/vy+eJeDtPZkH2eeLPD9/KzHPOV74CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYGlsbBxvM8JmQSKRGOges7dz7P1zbZZ2PQYAAAAACrDl7i9tybvZbffv3/8Mu32ffeycpqamde4xezvAPrbR714CAAAAQMWw5W6WLXnzetzf5+7bEjimx2MZP3sHAAAAABXHFr2JNou77tvyd8gWvvU2Q7ses9tp9+6gnz0EAAAAgIrS0NDw+7bg3eq26+vr/8wWwP+wud2WwvO6/oy9n6+rqzu9t+f6/PPPDQAAAMiimj0DYowrfrYE/rO9/bYte691fgQ8quvn9n6ulOdxL6KDB39uPvxQV5wTbvKCm9xo9sNNZrS7Va9hQGyxRa/Blr9b3LYrgPb+DHdrH1vb+ZjdbNxSynO54XAvpo4OXXFOuMkLbnKj2Q83mdHuVs2eATHFfbRrS99cm4vcqV+6Hrfby5uamobYrGxoaEiU8lyahwM3ecFNbjT74SYz2t2q1zKgJtA8HLjJC25yo9kPN5nR7ua7P4BwNA8HbvKCm9xo9sNNZrS7+e4PIBzNw4GbvOAmN5r9cJMZ7W6++wMIR/Nw4CYvuMmNZj/cZEa7m+/+AMLRPBy4yQtucqPZDzeZ0e7muz+AcDQPB27ygpvcaPbDTWa0u/nuDyAczcOBm7zgJjea/XCTGe1uvvsDCEfzcOAmL7jJjWY/3GRGu5vv/gDC0TwcuMkLbnKj2Q83mdHu5rs/gHA0Dwdu8oKb3Gj2w01mtLv57g8gHM3DgZu84CY3mv1wkxntbr77AwhH83DgJi+4yY1mP9xkRrub7/4AwtE8HLjJC25yo9kPN5nR7ua7P4BwNA8HbvKCm9xo9sNNZrS7+e4PIBzNw4GbvOAmN5r9cJMZ7W6++wMIR/Nw4CYvuMmNZj/cZEa7m+/+AMLRPBy4yQtucqPZDzeZ0e7muz+AcDQPB27ygpvcaPbDTWa0u/nuDyAczcOBm7zgJjea/XCTGe1uvvsDCEfzcOAmL7jJjWY/3GRGu5vv/gDC0TwcuMkLbnKj2Q83mdHu5rs/gHA0Dwdu8oKb3Gj2w01mtLv57g8gHM3DgZu84CY3mv1wkxntbr77AwhH83DgJi+4yY1mP9xkRrub7/4AwtE8HLjJC25yo9kPN5nR7ua7P4BwNA8HbvKCm9xo9sNNZrS7+e4PIBzNw4GbvOAmN5r9cJMZ7W6++wMIR/Nw4CYvuMmNZj/cZEa7m+/+AMLRPBy4yQtucqPZDzeZ0e7muz+AcDQPB27ygpvcaPbDTWa0u/nuDyAczcOBm7zgJjea/XCTGa1uQfFjk77rTnNg2P9d4LtDgAcaGxv/oaGh4fympqaxiUTiT9xj9naOffxcm6V2e2Apz6NxODQPPm5yo9lNux9uMqPVLX33BpO8+HxzYPj5+6rbNCB29OvX71u25E3pum+3l9nCd44tg+vcfXs7wD62sZTn0jgcmgcfN7nR7KbdDzeZ0eiWfeqZsPwlR19oDgz7wf+qVs+A+HKaLXnv1NfX/9mAAQN+z5a/yfb+fHs7pusP2AKYKeWJtA2H5sHHTXY0u2n3w01mtLnld78dFj9XAHNPPs13AGsV9/GvLXm/tHnE3j3N3q62Gdr1c7ud7t+//xm9PY8bjoMHo0HRFOeEm7zgJjea/XCTGU1uQbLNpC4ZF5a/9Ia7QqeqlgyIJ4MGDfoN97GvLYF/bW93JRKJ25qamm6yt+d1/Rl7P19XV3d6b89lAAAAILZ89l//ZdKXz4ve+bvuKvP5Z5+Fj1e3aUAs6Tzw45zOu1+3JXC7fWyefWxUjz+TK+W53ItIw29Hmn/zw01HNLtp98NNZjS4dXR8YtpWXR2Wv+a5l5qOTMcRt6oUDIg3tvCNtAXv73vcX1ZfX/9te7vW3bfbdrNxSynP5YYjepHpinPCTV5wkxvNfrjJjAa39D33huUvNWm0Kb7fcpRbtToGxJtvuFO+2AxzB3648ucetNvLbTEcYrOyoaEhUcoTSR8OzYOPm65odtPuh5vMSHfLPbstOuJ31AUmv3P3MW7VrRmgHsnDoXnwcfO/L7jhh5vsSHYr7NlrkmOGhQUwu/Wx47r57g8gHKnDoXnwccNNYjT74SYzUt2KqYxJTZ0Qlr/229ed0M13fwDhSBwOzYOPG25So9kPN5mR6BbkDpmWRdERv63Ll5qg8NEJ3Xz3BxCOtOHQPPi44SY5mv1wkxlpbkHwiWm74broiN9Z00zQXvxSN9/9AYQjaTg0Dz5uuEmPZj/cZEaaW+b+B6IjfieMNIV9qV7dfPcHEI6k4dA8+LjhJj2a/XCTGUluue07THLEEJMcOdTkX9lVkpvv/gDCkTIcmgcfN9w0RLMfbjIjxa3w9j6THDc8fPcv8/CWkt189wcQjoTh0Dz4uOGmJZr9cJMZCW7FlpxJTZ8UHfF7y80n5ea7P4Bw4j4cmgcfN9w0RbMfbjITd7cgf9i0LFkYlr+WpUtMUDh8Um6++wMIJ87DoXnwccNNWzT74SYzcXYLj/hdc2N0xO/MKabYVjhpN9/9AYQT1+HQPPi44eZ7X/DDDTe/yWzcFF3mbfwIU9j7wSm5+e4PIJy4DofmwccNN9/7gh9uuPlL7sVXoiN+bdz2qbr57g8gnDgOh+bBxw03jW7a/XCTmTi6uXf73Lt+4RG/GzeV5ea7P4Bw4jYcmgcfN9y0umn3w01m4ubmvufnvu/nyl/bmpvC7wGW4+a7P4Bw4jQcmgcfN9w0u2n3w01m4uTmjvB1R/qGR/wuWRgeAVyum+/+AMKJy3BoHnzccNPupt0PN5mJk1v7rbdEl3mbPik8918l3Hz3BxBOXIZD8+Djhpt2N+1+uMlMXNzc1T3CI37HDTeFd/ZXzM13fwDhxGE4NA8+brjVgpt2P9xkJg5u7rq+7vq+4RG/23dU1M13fwDh+B4OzYOPG2614qbdDzeZ8e1W2JcyqQkjoyN+73+g4m6++wMIh8GXF9xkRrObdj/cZManW9BeNM2zpkVH/N5wXVlH/J7IzXd/AOEw+PKCm8xodtPuh5vM+HILih+b1uVLoyN+F80zQe5QVdx89wcQDoMvL7jJjGY37X64yYwvt/b1t0dH/E6baIqpTNXcfPcHEA6DLy+4yYxmN+1+uMmMD7fs1sejI37HDDOFPXur6ua7P4BwGHx5wU1mNLtp98NNZvraLb9zt0mOuiAsgLlnt1XdzXd/AOEw+PKCm8xodtPuh5vM9KVb8f0Wk5o0Oix/6Xvu7RM33/0BhMPgywtuMqPZTbsfbjLTV25BusM0z7k0OuJ31TUVP+L3RG6++wMIh8GXF9xkRrObdj/cZKYv3MIjfn+8PDrid8FsE2Q/7DM33/0BhMPgywtuMqPZTbsfbjLTF27pDXdFR/xOGWeKyfY+dfPdH0A4DL684CYzmt20++EmM9V2yz75dHTE7+iLTH73233u5rs/gHAYfHnBTWY0u2n3w01mqumW3/2WLX4XhgUw+9QzXtx89wcQDoMvL7jJjGY37X64yUy13IoH2kxq8tjoiN+7N3hz890fwAODLE1NTVeceeaZv9nz8UQiMaexsfFcm6V2e2Apz8XgywtuMqPZTbsfbjJTDTd3kEfz/Flh+Wu9emV4EIgvt+o0DIg1ttx9z5a8X9kSeNimzW5nbb5rt9e5n9vbAfb+xlKei8GXF9xkRrObdj/cZKbSbuERv9deFZa/5rkzTZDp8OpW3aYBscSWux/Ym9Pcdr9+/b5lC+EwW/rm29sxPf5MppTnYvDlBTeZ0eym3Q83mam0W/qnP42O+J08xhQ/aPXuVqWKAVKwRW+WvfmqvV1tM7TH4+n+/fuf0dvfd8Nx8GD0YtIU54SbvOAmN5r9cJOZSrrlnn0+OuJ31IWm8PqbsXCrarmAeGNL3v9OJBL/6rabmprW2O3zun5m7+fr6upO7+05DAAAAJyQX7U2m9TYYWEB/OTFbb535wjV7BcQc2zJe3bQoEF/0LntPgIe1eNnuVKew72I+M1PVnCTGc1u2v1wk5lKuAXNaZOaOj464veO9d6derpVq1tA/DnNlrz/trffcHfs9nfcu4Buu76+vtGypZQnccPhXky+v6sR9+9+xCm4yYxmN+1+uMlMuW5B7qBpWTg3OuJ35TJvR/yeyK2K/QLizKBBg37bFr7Wno8lEonl9rEhNisbGhoSpTwPgy8vuMmMZjftfrjJTDluQfCJabt+VXTE7+zpJkgH3n2+6FaddgE1A4MvL7jJjGY37X64yUw5bumf3R8d8TtxtCnub/bucjw33/0BhMPgywtuMqPZTbsfbjJzqm655180yRFDTHLkBSb/6uvePU7k5rs/gHAYfHnBTWY0u2n3w01mTsWt8NY+kxw7PLrG75at3h2+zM13fwDhMPjygpvMaHbT7oebzJysW7Ela1LTJ4Xlr33dbd73vzc33/0BhMPgywtuMqPZTbsfbjJzMm5B/pBpWbIgOuJ32RUmKHzkff97c/PdH0A4DL684CYzmt20++EmM6W6hUf83rQ6OuL3sqkmaCt43/dS3Hz3BxBOrQ++xOAmM5rdtPvhJjOlumUe2hhd5m3CSFN474D3/S7VzXd/AOHU+uBLDG4yo9lNux9uMlOKW+7FlzuP+B1qci/t9L7PJ+Pmuz+AcGp58KUGN5nR7KbdDzeZ6c2t8O77Jjl+RPjuX2bzw97392TdfPcHEE6tDr7k4CYzmt20++EmM1/mVmzNm+ZLL4mO+L15Tfg9QN/7e7JuvvsDCKcWB196cJMZzW7a/XCTmRO5BYXDpuXKxWH5c7fuvu99PRU33/0BhFNrg68huMmMZjftfrjJzInc2m+5OTrid8Yl4TuBvvfzVN189wcQTq0NvobgJjOa3bT74SYzx3PLbH4kOuJ33MWm8M5+7/tYjpvv/gDCqaXB1xLcZEazm3Y/3GTmi275l3aGR/u6o35zL7zsff/KdfPdH0A4tTL4moKbzGh20+6Hm8z0dCu8lwzP8xce8fvgQ973rRJuvvsDCKcWBt/3vuCGm3Y37X64yUyXW5AumubLpoXlr+3GG8Qd8XsiN9/9AYSjffBxkxXc5EazH24y45w+//RT07r8yuiI38Xzw2v++t6vSrn57g8gHM2Dj5u84CY3mv1wk5nQ6Z67wvKXmjbRFFuy3vepkm6++wMIR/Pg4yYvuMmNZj/cZCa79bHoiN+xw03hrfe870+l1813fwDhaB18zf+o4SYzmt20++EmL7kXXjLJkReEBTC37QXv+1ONdfPdH0A4Gge/azhwkxfc5EazH26ykn/1dZMcfVFY/g4/vkWVW891890fQDjaBr/ncOAmL7jJjWY/3OQk/8Y74UmeXflL371BldsX1813fwDhaB4O3OQFN7nR7IebjLgre6QmjgrLX/utt9jHPlHjdrx1890fQDiahwM3ecFNbjT74Rb/FPc3m9SUcdG5/m64zgTFj9W4nWjdfPcHEI7m4cBNXnCTG81+uMU7xWTapGZMDstf61UrTFD4SI3bl62b7/4AwtE8HLjJC25yo9kPt/im2JozzbOnRyd6XrrEBLnuEz1Ld+tt3Xz3BxCO5uHATV5wkxvNfrjFM0E6MC0LZkflb9E8E2Q61LiVsm6++wMIR/Nw4CYvuMmNZj/c4pcgd9C0XLEoLH/Nc2eaoK2gxq3UdfPdH0A4mocDN3nBTW40++EWrwT5w6Z1xbKo/M2cYorNx7/Em0S3k1k33/0BhKN5OHCTF9zkRrMfbvGJO7q3bdU10fV9p04wxQ9a1bid7Lr57g8gHM3DgZu84CY3mv1wi0eC4BPTtvamqPxNGmMKew+ocTuVdfPdH8ATZ5999uDGxsZlDQ0N5ycSifPcY/Z2jn3sXJuldntgKc+jeThwkxfc5EazH27+48pf+x3rw/KXHD/CFPbsVeN2qutW3ZYBsaWpqen5/v37n1FXV9fPFr7HbOE7xz62rvNnA+xjG0t5Hs3DgZu84CY3mv1w85/0ffdF5W/MMJPf9aYqt1Ndt+q2DIgltux9z5a8zT0eOs3en28fH9P1gC2AmVKeS/Nw4CYvuMmNZj/c/CazaXNU/kZdYHI7XlXlVs66VbxcQPyxZW+mLXiP2sL3L/Z2fENDw9/Y29U2Q7v+jN1Ou3cIe3suNxwHD0YvJk1xTrjJC25yo9kPN3/JPfFkVP5GDDG557apcit33arbNCCW2HI322Zb592v2e09thTe1PVdQIe9n6+rqzu9t+cyAAAAMeQXu3eFxc8VwE9e3OZ7d2JH1UoGxBdb7obYsreh6757t89mkX1sVI8/kyvludyLSOtvR7jJC25yo9kPt75P/uWdJjnqwrD8ZTdtVuVWqXWrRr+AmNN54MdTnXe/brffrK+v/7a9XesesNt2s3FLKc/lhsO9mHx/n6Ea34/ATV5wkxvNfrj1bfKvvRke7OHKX/qee1W5VXLdqlYyIN7YgjfCZkoikZjb1NT0HfeY3V7u3h20WdnQ0JAo5Xk0Dwdu8oKb3Gj2w63vUnjrvfA0L678ta+/PTz9ixa3Sq9bdVsGqEfzcOAmL7jJjWY/3PomhfcOmNTkMWH5a1tzY1nlL25u1Vg33/0BhKN5OHCTF9zkRrMfbtWPu6RbatrEqPytujq85JsWt2qtm+/+AMLRPBy4yQtucqPZD7fqpticNc0zp4Tlr3XFUhPkD6txq+a6+e4PIBzNw4GbvOAmN5r9cKtegraCaZ47Myx/LUsWmiD7oRq3aq+b7/4AwtE8HLjJC25yo9kPt+okyHSYlsXzo/K3YLYJ0oEat75YN9/9AYSjeThwkxfc5EazH26VT5A/ZFqXLQnLX/Os6abYmlPj1lfr5rs/gHA0Dwdu8oKb3Gj2w62yCQofmdarV4blLzV9kikm29W49eW6+e4PIBzNw4GbvOAmN5r9cKtc3NG9bauvj8rflHGmsC+lxq2v1813fwDhaB4O3OQFN7nR7IdbZeLO69d+2y1R+Zs4yhTe2a/Gzce6+e4PIBzNw4GbvOAmN5r9cKtM0nffHZa/5LjhJv/G26rcfKyb7/4AwtE8HLjJC25yo9kPt/KTeeDBqPyNvtDkX31dlZuvdfPdH0A4mocDN3nBTW40++FWXrKPbo3K38gLTG77DlVuPtfNd38A4WgeDtzkBTe50eyH26kn+/RzJjliSJjsU8+ocvO9br77AwhH83DgJi+4yY1mP9xOLbkXXgrf9XPv/mW3bFXl5jsUQCgbzcOBm7zgJjea/XA7+bjv+SVHXxSWP/f9P01ucQgFEMpG83DgJi+4yY1mP9xOLvk33jHJcReH5S+9YYMqt7iEAghlo3k4cJMX3ORGsx9upced28+d48+Vv/ZbbwnP/afFLU6hAELZaB4O3OQFN7nR7IdbaSnubw6v7uHKX9sN14VX/dDiFrdQAKFsNA8HbvKCm9xo9sOt9xSTaZOaMTksf61XrQiv96vFLY6hAELZaB4O3OQFN7nR7Ifbl6fYmjPNs6eH5a9l6RIT5A5596qFdfPdH0A4mocDN3nBTW40++F24gTpwLQsmB2Vv0XzTJDp8O5UK+vmuz+AcDQPB27ygpvcaPbD7fgJcgdNyxWLwvLXPHemCdoK3n1qad189wcQjubhwE1ecJMbzX64HZsgf9i0rlgWlb+ZU0yxOevdpdbWzXd/AOFoHg7c5AU3udHsh9vRcUf3tq26Jix/qakTTPGDVu8etbhuvvsDCEfzcOAmL7jJjWY/3LrjzuvXtvamqPxNGmMKew94d6jVdfPdH0A4mocDN3nBTW40++EWxZW/9jvWh+UvOX6EKezZ633/a3ndfPcHEI7m4cBNXnCTG81+uEVJ33dfVP7GDDP5XW963/daXzff/QGEo3k4cJMX3ORGsx9uPzeZTZuj8jfqApPb8ar3/WbdKIBQJpqHAzd5wU1uNPvVulv28Sej8jdiiMk9u837PrNuFECoAJqHAzd5wU1uNPvVslvuue1h8XMFMPvYE973l3XrdvPdH0A4mocDN3nBTW40+9WqW+6lnSY56sKw/LmPgH3vK+t2tJvv/gCeaGpq+nN78/X+/fufkUgkGtxj9nZOY2PjuTZL7fbAUp5H83DgJi+4yY1mv1p0y7/2Zniwhyt/6Xvu9b6frNuxblUtGRBfbMnbY0vgQZvNdXV1/WzhO8dur3M/s7cD7M83lvI8mocDN3nBTW40+9WaW+Gt98LTvLjy177+9vD0L773k3U71q26LQNiiy15w79wf74tgWO67tsCmCnleTQPB27ygpvcaParJbfCewdMavKYsPy1rblRbPmrhXWrdK8AIdjCt7KhoeH7tvTNHTRo0B/ZwrfaZmjXz+122n083NvzuOE4eDB6MWmKc8JNXnCTG81+teIWHGg1qWkTo/K36mrTEXzsff9YtxO7VbdlQJz5qvuffv36fcuWvVdtIbzJlsHzun5o7+fr6upO7+1JDAAA1Dy//vgj0zZ7Wlj+cteuMJ//+te+dwl6oZoFA2JKQ0PDv9uCd23n3a/ZAvhLe3+eLYCjuv6MvZ8r5bnci0jrb0e4yQtucqPZT7vbp//xC9Myb2ZY/lqWLDQduQ+97xfr1rtbVQoGxBtbAP+uvr7+22578ODBf2gL4NPuvr1d6x6z23azcUspz+WGw72YfH+fge9+4Iab7Gj20+zWke0wmaULo/K3YLYJ0oH/fWLdSnKrZs+AGOMO+HDv+Nmid6U7CrjzseVNTU1DOr8fmCjleTQPB27ygpvcaPbT6hbkDprWZUvC8tc8a7optua87xPrVrpbdVsGqEfzcOAmL7jJjWY/jW5BezH8uNeVv9aZl5gg1e59n1i3k3Pz3R9AOJqHAzd5wU1uNPtpcyumMqZ5bvSdv+bLppr//rBDjZvmdfuim+/+AMLRPBy4yQtucqPZT5Nb8f1m03zpJVH5mz/LBC1ZNW6a1+14br77AwhH83DgJi+4yY1mPy1uhXf2m9SUcdEBH1csCg/40OKmed1O5Oa7P4BwNA8HbvKCm9xo9tPgln9tj0lOGBl95++qFSbIHVLjpnndvszNd38A4WgeDtzkBTe50ewn3S334ismOWZYdIWPG28wQeEjNW6a1603N9/9AYSjeThwkxfc5Eazn2S37NPPmuTIC8Ly175+/THX9pXspnndSnHz3R9AOJqHAzd5wU1uNPtJdcs8/IhJjhgSlr/M/fcfU/4ku2let1LdfPcHEI7m4cBNXnCTG81+0txc0Uvfc09Y/FwBzD66VY2b5nU7WTff/QGEo3k4cJMX3ORGs58kt6D4sWlfd1tU/kZdaHLPblPjpnndTsXNd38A4WgeDtzkBTe50ewnxS0oHDZt16+Kyt/Y4Sb/0k41bprX7VTdfPcHEI7m4cBNXnCTG81+EtyC7IemdeWysPylJo42+d1vq3HTvG7luPnuDyAczcOBm7zgJjea/eLuFl3Xd0FU/qZOMIV3P1DjpnndynXz3R9AOJqHAzd5wU1uNPvF2e3o6/pOM8UPWtW4aV63Srj57g8gHM3DgZu84CY3mv3i6lbc32yaZ0TX9W1ZMNsUW3Jq3DSvW6XcfPcHEI7m4cBNXnCTG81+cXQrvLXPpC7pvK7vlYvD6/pqcdO8bpV0890fQDiahwM3ecFNbjT7xc0tv+vN417XV4Ob5nWrtJvv/gDC0TwcuMkLbnKj2S9ObrkXXu6+ru9Nq4+6rq90N83rVg033/0BhKN5OHCTF9zkRrNfXNyyTz3TfV3fO+447qXdpLppXrdqufnuDyAczcOBm7zgJjea/eLgltn8cI/r+j6gyk3zulXTzXd/AOFoHg7c5AU3udHs59MtvK7vT3/afV3frY+pcdO8bn3h5rs/gHA0Dwdu8oKb3Gj28+UWXtf3tlu6r+v73HY1bprXra/cfPcHEI7m4cBNXnCTG81+PtzC6/ped21U/sYNN/lXdqlx07xufenmuz+AcDQPB27ygpvcaPbra7fwur4rlnZf1/eN0q7rK8FN87r1tZvv/gDC0TwcuMkLbnKj2a8v3YK2gmlZPL/7ur57S7+ub9zdNK+bDzff/QGEo3k4cJMX3ORGs19fuRVTadM859JTvq5vnN00r5svN9/9AYSjeThwkxfc5EazX1+4FfalTGrG5LKu6xtXN83r5tPNd38A4WgeDtzkBTe50exXbbfCW++Z1OSxUflberkJ0h1q3DSvm2833/0BhKN5OHCTF9zkRrNfNd3yu94wyfEjouv6Xv3jsq7rGzc339Hu5rs/gHA0Dwdu8oKb3Gj2q5Zb7oWXuq/ru+bG8Lx/WtziEO1uvvsDCEfzcOAmL7jJjWa/arhln3zaJEcODctf+q47K3Jd37i4xSXa3Xz3BxCO5uHATV5wkxvNfpV2y2zaHJ3g2V3X94EHVbnFKdrdfPcH8ExjY+MNiURioNu2t3Ps/XNtlnY91huahwM3ecFNbjT7VcotvK7vT37S47q+j6txi2O0u1W3XUCssSXvL2zZO1BfX3+W3T6nqalpnXvc3g6wj28s5Tk0Dwdu8oKb3Gj2q4RbeF3fW26u6nV9WdEoX2MAACAASURBVLfacqtuw4A4c5otff9my97zrgDa2/n2/piuH9oCmCnlSTQPB27ygpvcaPYr1y3Iu+v6XtN5Xd+LTf6V17w7sW6yQwGsYWzZ+6G9+UZXAbSFb7XN0K6f2+10//79z+jtedxwHDwYvZg0xTnhJi+4yY1mv3LcOtx1fZd3Xtd30mhT2POudx/WTX6cU1VLBsQTW/7+xBa/P3fbtuhtGzx48Nn2/hr7+Hldf8bez9fV1Z3e23MZAACoCp/+4hcms3RhdI6/GZPM/8vnfO8SKKKaPQNiii13wztzsS2A+2zxu9TeLrK3o3r8mVwpz+VeRFp/O8JNXnCTG81+p+IW9Lyu76xpJki2efdg3fSEdwAhfAew8zuA37Hba91j9r7dbNxSyt93w+FeTL6/z8B3P3DDTXY0+52sW3hd3+mToku7LZxjiq19c11f1q223KrbLiDWJBKJC907fTbXDhw48Hft/eXue4D2/sqGhoZEKc+heThwkxfc5Eaz38m4Ffbs7XFd3yV9el1f1q223KrdMUA5mocDN3nBTW40+5Xqlt+5u/u6vtf82AT5vr2uL+tWW26++wMIR/Nw4CYvuMmNZr9S3HLbd5jk6Iui6/quvcnLdX1Zt9py890fQDiahwM3ecFNbjT79eaWfeKpHtf1vcvbdX1Zt9py890fQDiahwM3ecFNbjT7fZlbZuOm7uv6PviQ931l3WrHzXd/AOFoHg7c5AU3udHsdzy38Lq+d9/dfV3fx57wvp+sW225+e4PIBzNw4GbvOAmN5r9vugWXtf35rVR+Rt9ock9/4L3fWTdas/Nd38A4WgeDtzkBTe50ezX0y28ru+qHtf1ffV17/vHutWmm+/+AMLRPBy4yQtucqPZr8stvK7vj67ovK7vGFN4813v+8a61a6b7/4AwtE8HLjJC25yo9nPObnr+rYsnheVv2kTTeG9A973i3WrbTff/QGEo3k4cJMX3ORGs1+Qajft82d2Xtd3uikeaPO+T6wbbr77AwhH83DgJi+4yY1Wv8Lb+0zzkev6zjXF1rz3fWLdcKMAQtloHg7c5AU3udHol33qGZMcMywsf9mrlpmObLyv68u61Zab7/4AwtE8HLjJC25yo8nPHenbvu62Iyd4Tt++znz+61+rcNO8brXm5rs/gHA0Dwdu8oKb3GjxKybTpuXyBVH5GzPMZJ9+Vo2b5nWrRTff/QGEo3k4cJMX3ORGg19+526Tmjw2Otjjsqmm8M5+NW6a161W3Xz3BxCO5uHATV5wkxvJfu6ybu46vsmRQ8Py13rVChO0F1W4aV63Wnfz3R9AOJqHAzd5wU1upPoF6Q7Tdu1VR67pm7n//rAQanDTvG64UQChTDQPB27ygpvcSPQr7P0gPK9fdGWP0Sb/8i41bprXDTcKIFQAzcOBm7zgJjfS/HLPbjPJccO7z+/3JSd3luamed1w63bz3R9AOJqHAzd5wU1upPgFhY9M+x3rj5zipf2Wm02QP6TCTfO64Xasm+/+AMLRPBy4yQtuciPBr9icNS1XLo7K3+iLTPbxJ9W4aV433I7v5rs/gHA0Dwdu8oKb3MTdL//aHpOaMj76vt+MyaawZ68aN83rhtuJ3Xz3BxCO5uHATV5wk5u4+oWneNn8sEmOuiA6xcvKZSZoK6hw07xuuPXu5rs/gHA0Dwdu8oKb3MTRL8h+aNquX3XkFC/pe+41QfFjFW6a1w230tx89wcQjubhwE1ecJObuPkV9qVM85xLo498J4w0uRdfUeOmed1wK93Nd38A4WgeDtzkBTe5iZNfbtuLJjl+RHRJt/mzTPH9ZjVumtcNt5Nz890fQDiahwM3ecFNbuLg5z7eTd+94cgpXtpuWm2C3Jef4kWKm+Z1w+3U3Hz3BxCO5uHATV5wkxvffsXWnGlddkVU/kZdaLKPPqbGTfO64Xbqbr77AwhH83DgJi+4yY1Pv/wb75jUtInR9/3sbf6Nt9W4aV433Mpz890fQDiahwM3ecFNbnz5uXf63Dt+4Slell0RvhOoxU3zuuFWvpvv/gDC0TwcuMkLbnLT135B7mD4Hb+u7/u57/6dyile4uimed1wq5yb7/4AnkgkEhc2Njb+wOaGpqamf+p8bI69f67NUrs9sJTn0TwcuMkLbnLTl37F91vCo3vD8jd+hMlt36HGTfO64VZZt+q2DIglZ5999mBb+t522w0NDf9ot3fbwneOvV3nHrO3A2wJ3FjKc2keDtzkBTe56Ss/dz6/1MRR0Sle5lwanu9Pi5vmdcOt8m7V7BkQY84666zfcbe26C2w5e9yW/rm29sxXT+3j2dKeR7Nw4GbvOAmN9X2C0/xcs+94RU9wlO83HBdeKUPDW6a1w236rlVq19A/PlmQ0PD+bborbfF73/Y29U2Q7t+aLfT/fv3P6O3J3HDcfBg9GLSFOeEm7zgJjfV9AvaC+E1fMOPfEdeYLIPP2L/I/iJCjffwU1mnFN1KwbEnqampiE2D9vcZIvgeT0ez9fV1Z3e2983AAAx5r/aWk3rZVPC8tcybYL55YH3fe8SQCyobruA2FNfX99o+dxmkS2Ao7oetwUwV8rfdy8irb8d4SYvuMlNNfxyTzxpkqMvisrfFYtM0JJV4xaX4CYzvANYo9hyN9YWvgfdtr39rk3WFsFv29u17rHOUrillOdyw+FeTL6/z8B3P3DDTXYq6RfkD5n2W24+coqX9jvWm6DwkQq3uAU3mXFO1ewZEFMGDx58pi14Izo//l3X0NDwp+7xRCKxvPOxlfaxRCnPpXk4cJMX3OSmUn7FA22mZeHcqPyNG25yz25T4xbH4CYzFEAoG83DgZu84CY3lfDLv7zLpCaNjk7xMmu6Kez9wLuX9rXDTWYogFA2mocDN3nBTW7K8QuCT0zm/vu7T/Fy7VUmSHd4d6qFtcNNZiiAUDaahwM3ecFNbk7VL2gvmtarV3ae4mWoyTz4UFgIffvUytrhJjMUQCgbzcOBm7zgJjen4ld4Z79pnhmd4iU1eazJ79zt3aPW1g43maEAQtloHg7c5AU3uTlZv+zTz5rkmGHRKV4WzzfFZNq7Qy2uHW4yQwGEstE8HLjJC25yU6pfUDhs2m9f132Kl3W3mSB/2Pv+1+ra4SYzFEAoG83DgZu84CY3pfgVU2nTsmRBVP7GDDPZp57xvt+1vna4yQwFEMpG83DgJi+4yU1vfu77falLxkWneJk5Jfz+n+99Zu1wkxoKIJSN5uHATV5wk5sT+YWneNm4KTzC15W/1qtWhEf++t5f1g43yaEAQtloHg7c5AU3uTmeX5DpMG2rrok+8h0xxKR/dr8Jih9731fWDjfpoQBC2WgeDtzkBTe5+aJfYe8B0zx7enSKl0mjw6t8+N5H1g43LaEAQtloHg7c5AU3uenpl3tuu0mOuzg6xcvCueH1fX3vH2uHm6ZQAKFsNA8HbvKCm9w4r88//dSk77yj+xQvN681Qf6Q931j7XDzvS/VcPPdH0A4mocDN3nBTW6ClqzJrrwyKn+jLzLZx57wvk+sHW6a3Xz3BxCO5uHATV5wk5n8SztNaur46BQvMyabwp693veJtcNNu5vv/gDC0TwcuMkLbrJSbM2bttXXH/nIN3etO8VLwft+sXa41YKb7/4AwtE8HLjJC24y4s7t567ikZo0Jip/4y422Ue2mM8/+0yFn+a1w01HKIBQNpqHAzd5wS3+KX7QalpXLDvyrp87sbM7yleLn+a1w01PKIBQNpqHAzd5wS2+cSdwDq/oMXZ4dG6/S8aZ3LPbwncDNfhpXjvc/O9LNdx89wcQjubhwE1ecItnCm/vC8/n1/WuX9vam0zQdvR3/ST7aV473PS6+e4PIBzNw4GbvOAWrwS5QyZ99waTHHlBdITvzCkm/+rravw0rx1u+t189wcQjubhwE1ecItP8jt3m+bLpkbv+tkCmN6wwRbCg2r8NK8dbrXh5rs/gHA0Dwdu8oKb/wTtRdO+ds2Rj3tbFs4xhbf2qfHTvHa41Zab7/4AwtE8HLjJC25+467hm5oyLip/Y4eHB324gz+0+GleO9xqz813fwDhaB4O3OQFNz8pJtvD07kcObXLiqXh6V60+GleO9xq1813fwDhaB4O3OQFt75NeGqXR7aY5PgR0aldJo0OT/DcdWoX6X6a1w433Hz3BxCO5uHATV5w67sU9n5gWpYs6D61y+rrTbE1p8ZP89rhhhsFEMpG83DgJi+4VT9B/rBJ33OvSY66MHrXb8Zkk9vxqho/zWuHG2493Xz3BxCO5uHATV5wq27yr+0xzbNnRO/6jRhi2tevN0H2QzV+mtcON9y+6Oa7P4BwNA8HbvKCW3USpDtM+223hqUvPKHzvMtM4c131fhpXjvccDuRm+/+AMLRPBy4yQtulU9u+w6TmjYxetdv9EUmc/8DJigcVuOnee1ww+3L3Hz3B/BEIpGYaDOmsbHxnsGDB5/d+dgce/9cm6V2e2Apz6N5OHCTF9wql2Jz1rStuqb7hM5LLzeFfSk1fprXDjfcSnGrbsuAWNLQ0PB9mz/t3P53W/getYXvnKampnXuMXs7wD62sZTn0jwcuMkLbuXHncIl+9gTJjVhZHSQh71190/l1C5x9NO8drjhdjJu1ewZEFNsuZtqC9+Nbtve/rEtfG/bzHPvCPb4M5lSnkvzcOAmL7iVF/cOn3un78ipXVZdE74TqMVP89rhhtvJulWrY0C8+Xp9ff1vuY3Oj4GvsrnBZmjXH7Db6f79+5/R2xO54Th4MHoxaYpzwk1ecDu1dBQ/MpkHHgi/4xe+6zd1gsm/sEONn+/gJjPa3apZMiDm9OvX71u26G0688wzf7OpqWmNLYPndf3M3s/X1dWd3ttzGAAQza9am037ojlHTu3S8ZM7zWe//KXv3QKAKlPdhgFx5qu2/C0766yzfsfdsYVvvi2Ao7p+aO/nSnkS9yLS+tsRbvKCW+npyH5o0nes7z61y+wZpvD6HjV+cQpuMqPdrVrlAmKOLXhjBw8efKbbdkf+1tfXf9vernX37bbdbNxSyvO44XAvJt/fZ+C7H7jhVnrclTvcFTzCd/1GXRhe2cNd4UOLX9yCm8xod6tmx4CY4o78tQXw57bkdXTmTvd4IpFYbh8fYrPS/plEKc+leThwkxfcvjzuWr1tN1zXfWqXJQvCa/r6dmPt5AY3maEAQtloHg7c5AW34yc8tctTz5jUpNFR+Rs/wmQeedQExY+9e7F2soObzFAAoWw0Dwdu8oLbsSl+0Gpaly898q5f61UrTDHZ7t2HtdMR3GSGAghlo3k4cJMX3Lrj3t3LbNxkkmOHR6d2uWScyT233bsHa6cruMkMBRDKRvNw4CYvuEUpvLXPtCycc+Rdv/a1a0zQXvTuwNr53xfccOty890fQDiahwM3eal1tyB3yKQ3bDDJkRdEp3a5bKrJ79ztfd9ZO9wkRrub7/4AwtE8HLjJSy275V993TTPnBK962cLYPruu8NC6Hu/WTvcpEa7m+/+AMLRPBy4yUstugVtBdO25qbuU7ssmmsKb+/zvr+sHW7So93Nd38A4WgeDtzkpZbc3Kldcs9uCw/uCMvf2OEms2lzrE7twtrhJjna3Xz3BxCO5uHATV5qxc2dxsWdzuXIqV1WLAtP9+J7H1k73DRFu5vv/gDC0TwcuMmLdrfPP/vMZB/ZYpLjLo5O7TJpTHiCZ/duoO/9Y+1w870vuJ2cm+/+AMLRPBy4yYtmt8Ked01m2eIj7/q13XiDKbbmve8Xa4cbbvJCAYSy0TwcuMmLRrf8G2+b1pXLjhS/5hmTTf6lnd73i7XDDTe5oQBC2WgeDtzkRZNbfvdbpnVF9yXcUhNHmUOPbDIduQ+97xtrhxtuskMBhLLRPBy4yYsGt/zre466dm9q4miT/tnPTEemQ7yb9rXDTVe0u/nuDyAczcOBm7xIdsu/9qZp/dEVXyh+95sg3SHeTfva4YabtFAAoWw0Dwdu8iLRLb/rDdO6bEl38Zs02mTuf8AEmQ7xbtrXDjfcpIYCCGWjeThwkxdJbu4avS1LexS/yWNM5oEHTZA9/nf8JLlpXzvccJMeCiCUjebhwE1eJLi5a/a2XLn46OL34EMnLH6S3LSvHW64aQkFEMpG83DgJi9xdguL3xWLuovfJeNM5qGNvRY/CW7a1w433HzvSzXcfPcHEI7m4cBNXuLm5q7QkX9l19HFb4otfhs3mSB3ULSb9rXDDTftbr77AwhH83DgJi9xcQuL38u2+C1ZcHTx27T5pItf3Ny0rx1uuNWKm+/+AMLRPBy4yYtvN1f8ci/tNC2X9yh+U8ebzOaHbfE7JNpN+9rhhlutufnuDyAczcOBm7z4cguL345XTMvi+T2K3wSTefiRsoufbzfta4cbbrXq5rs/gHA0Dwdu8tLXbmHxe9EWv0Vzu4vftIm2+G0xQb4yxa8W1k27H24yo93Nd38A4WgeDtzkpa/cwuL3wsumZeEXit8jj1a8+NXCumn3w01mtLv57g8gHM3DgZu8VNstLH7bd5iWBbO7i9/0SSb76FZb/A6LdvMdzX64yYx2N9/9AYSjeThwk5dquZ24+D1W9eJXC+um3Q83mdHu5rs/gHA0Dwdu8lJpt7D4Pf+iaZ4/60jxa55xiclufdwEhb4pfrWwbtr9cJMZ7W6++wMIR/Nw4CYvlXILih+b3HPbTfO8y7qL36W2+D32RJ8Xv1pYN+1+uMmMdjff/QGEo3k4cJOXct2OFL+5M7uL38wpJvv4k7b4fSTaLe7R7IebzGh3890fQDiahwM3eTlVt7D4PbvNNM+5tLv4XTbVZJ94ynvxq4V10+6Hm8xod/PdH8AjTU1N4+rr6/+2634ikZjT2Nh4rs1Suz2wlOfQPBy4ycvJurnil33muS8Uv2km++TT4c98+9TKumn3w01mtLtVr11AnDnNFrzJtgC+bsved90D9v459v46t21vB9jHN5byRJqHAzd5KdUtLH5P2+I3e3p38Ztli99Tz8Su+NXCumn3w01mtLtVs2RAzLEl786uAmhL33xbAsf0+FmmlOfQPBy4yUtvbmHxsyWveVaP4mdLYPbpZ2Nb/Gph3bT74SYz2t2q1S1AAD0LoL1dbTO0x8/S/fv3P6O353DDcfBg9GLSFOeEm7ycyK0j+Njknno6fJevu/jNMLlnngt/5nu/a33dtPvhJjPa3arZLyDmfOEdwDWJROK8rp/Z+/m6urrTe3sOAxBjPv/0U/Pzl180bXO63/FrX3CZ+cWuV83nn33me/cAALxRzX4BMec4HwGP6vqZvZ8r5Tnci0jrb0e4yUuX24fBRyb3xJPhKVyOvOM3d6bJPbdNzDt+tbRu2v1wkxntbtXqFiCALxTA77h3Ad12fX29fbhxSynPEf7H9kP/32fgux+4hSkeNp/s2H6c4rc99t/xq+l1U+6Hm8xod6tmv4AYk0gkJtqSt9fmLrv9vc7HltsSOMRmZUNDQ6KU59E8HLjJiLtcW37Xm6b9lptNauLo7uI37zKTe/4F8cVP67rVkh9uMqPdraolA/SjeThwi3cK7+w36Q0bTGr6pCOlzyWzbLHJb38xLIa+95F1ww83udHu5rs/gHA0Dwdu8UvxQJvJPPDgUZdqi87hN92k77vPFN9vFuumed1q3Q83mdHu5rs/gHA0Dwdu8UjQVjDZR7ealisXm+SIIUdKX2rqeNN+x3pT2LP3yLt90tw0rxt+uEmPdjff/QGEo3k4cPOXIHcovDZv61UrTHLUhd3v9o0fYdrW3Gjyr7x23O/2SXDTvG744aYp2t189wcQjubhwK1v4wpd/uVdpu2m1WHRO1L6bAFsvfrH0ZG8thhKdNO8bvjhhpu8UAChbDQPB27Vj/votvDmu6b99nUmNWVcd+kbMcS0LL3cZLc+boL2okg3zeuGH264yQ4FEMpG83DgVr0U9qVM+p57TfNl044+mGP+LJN58CFTTLaLddO8bvjhhpuOUAChbDQPB26VTbElazKbNpuWRfOOKn2pGZNN+u67TeHdD8S6aV43/HDDzf++VMPNd38A4WgeDtzKT5DpMNknnjaty5ea5Mih3aVv0mjTfustJv/anoqer491kxvNfrjJjHY33/0BhKN5OHA7tQSFwya3fYdpu+5akxwzrPvdPrvddv0qk3vh5fDPSHTTvG6+o9kPN5nR7ua7P4BwNA8HbqXnRJdjc+/6ta5YZrJPPWOC7Ici3eISzW7a/XCTGe1uvvsDCEfzcODWewrvvn/cy7G1LJ5vMpsfMcWWnFi3uEWzm3Y/3GRGu5vv/gDC0TwcuB0/vV6ObX+zWLc4R7Obdj/cZEa7m+/+AMLRPBy4dSe6HNtjx16Obcp4077+6MuxSXOTEs1u2v1wkxntbr77AwhH83DUutuXXo7tptUm/8qu416OTYKbxGh20+6Hm8xod/PdH0A4moejFt0qcTm2uLpJj2Y37X64yYx2N9/9AYSjeThqxe1LL8d25WKT3frYSV2OLU5umqLZTbsfbjKj3c13fwDhaB4O7W7F/dW5HFsc3DSvm0Y37X64yYx2N9/9AYSjeTi0ubkDOXI7XjWZe+816SsXHudybBsqcjk21g03/HDTEO1uvvsDCEfzcEh2C/KHTH732yaz+WHTdsN1pvmyqUcVvmpejo11ww0/3DREu5vv/gDC0TwcUtzC7/C9lwyvudt+262mZeHco4/a7Sp8E0eF1+RN//Sn5j/ffct0FKtzOTbWDTf8cNMQ7W6++wMIR/NwxNXNXV0j98JLJv2Tn5jWH11pUhNGHlP2kqMvNC2L5pn2dbeFl2Er7EsdeZcvzm6a1w232vXDTWa0u/nuDyAczcMRB7cgdzC8xm7moY2mbdU14Xf1jil77sCNy6aZttXXh5dfy7/xjgnyJ353Ly5umtcNN/xwkx/tbr77AwhH83D0tZs7B5+7tm72sSdM+81rw6NxkyMvOPaj3MljTOuPl4eXXcu9tPOkT9Gi/R813GRGsx9uMqPdzXd/AOFoHo5quxWTaZN7/gWTvusu07L0cpMcd/Gx7+6NGWZaliwML7eWe+Z5U/ygtewDNrT/o4abzGj2w01mtLv57g8gHM3DUUm3INNh8q++bjL3PxBeUSM1dcKxZW/EENM851LTtuZGk92y1RTees8EhY9i7xan4CY3mv1wkxntbr77AwhH83Ccqpsrba68ZR/dGpY5V+pcuTvmo1xbAl0ZdKXQlcMg3RF7t7gHN7nR7IebzGh3890fQDiah6MUN/dxrPtY1n08237H+vDjWvex7THv7o27OPyY133c6z72dR//xt1NYnCTG81+uMmMdjff/QGEo3k4jufmDrjIv7QzPADDHYiRmjz22LI3cmh4AIc7kMMd0OEO7HAHePh26s1NQ3CTG81+uMmMdjff/QGEo3k4Pv/1r03hzXdM5uFHwlOsNM+adtxTsLhTs7hTtLhTtbhTtgTZD73vf29umtcNN5nR7IebzGh3890fQDhShsO9A+fevSvubw7Pk5fb8Up4gmR33rz0Pfea9tvXhSWvdeUy07J4fnhevdToi44texNGhidfdidhdidjLrZkvbudyuBLWTfcasNNux9uMqPdzXd/gBiRSCTmNDY2nmuz1G4PLOXv9PVwuCJXbCuEV7Zw17rNvdhZ5DZtDi9x5q584a5927piWXgljOaZU0xq4ujjHoTRa9zVNBbODS+v5i6z5i63puGaudr/UcNNZjT74SYz2t2q3SlACLbwndPU1LTObdvbAbYEbizl753qcIRFrjVvS9UBk399j8m98HJYso4UudtuMW3XXxteu9aVsKjIjTq1Itd5Pj131G3z3Jmm5crFpvWaH5u2tTeZ9F13hkfhZh99zOSe2x4ejVt4e58JUu3hR8BaB1/zP2q4yYxmP9xkRrtbdVsFiMGWvvm2BI7pum8LYKaUv/f5p5+aoDVnCnttkXvNFrntO0z28SdNZuOm8GPS9lttkbvOFrkfXWFaFsw2zTMuMcnjXbu21IwbblLTJprmeZeFR9W2XnuVab95jUlvuMtkHnjQZLc+Hh5lm9+52xTe2W+KqbQJcocYfNzER7Obdj/cZEa7W/UaBYjCFr7VNkN73E/379//jC/7OwcuPu+hUy5y40eY5umTTMv8WaZ12RLTtupq037LWpO+e4PJPPSQLZFPmPz2F03htTdM0R1F675rVzgcvmj7IgcPRoPvbvvq/xM33GrVTbsfbjKj3a36zQJE0NTUtCaRSJzX436+rq7u9C/7OweGn/dg8uLzPra3Lcnh579+YPj5T9lSeN8Hw89bc2DYeUvtz2Z8cPH5ww8M/+E/77/oh3/9wdAf/NHbw/7P7+/+q7/6ZvWNAAAAAOBL6fwIeFSP+zmf+wMAAAAAVcYWvu+4dwHddn19faNli+99AgAAAIAqk0gkltsSOMRmZUNDQ8L3/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADACUkkEnMaGxvPtVlqtwf63p9q0NTUNK6+vv5vfe9HpbHrNdFd99mu3T2DBw8+2/f+VBLrdaH1+oHNDXb9/sn3/lQD56Zt5uxa/bm9+bq7/KS2U1CdffbZg+2aLbNe5/e82pJ0Blnsul1x5pln/qbvfakGds3+wa2ZdRxrb//U9/5UEus23maEzQLr9j997w8Iwv4jdo4dinVu294OsC+ijb73qcKcZh0nW7fXrdt3fe9MJbHD/v2uf8zs7b9bv0d971OlcP+htWv2ttu2bv/o1s/3PlUa+7r8C7tmB+wvJmf53pdKYp322PU6aLO5rq6un+/9qSTW6XlXbJ2X9XzM9/5UCvta/J71+ZX1O2zTZrez9nX5bd/7VQn69ev3Leszpeu+K/A+96eS2HX7S+tzs9t2r0u7fZ/vfQJBdF42bkzXffsCyvjcn2phuRM0XwAAA5NJREFUve7UVgCtz1S7dje6bXv7x/b+W773qZKcddZZv+Nu3W+21m+x7/2pMO4Xk39zhUJbAbROw33vQzVwJcmV2h4PneZtZyqMe6f9K50+rjBZ12Ged6mSnGbX7R07Z382YMCA33NvCPjeoUph122WdZvX4/4+n/sDwrAvmNU2Q3vcT7vfJHzuUzXQWAAtX7f/qP2W2+j8GPgq3ztUYb7pPraxXuu/oug/tg67Xj+0N9+wbtsUFkB39aHvu/8wDRo06I9870+lsD4z3bvsdu3+xd5OsI5/43ufqoErFfbmq773o5J0/jvyS5tH7N1v+t6fStH5FaAjvxzb1+ghV+B97hMIwl0zuOd3Wez9fF1d3ek+96kaKC2AIZ0fcWzS+v2dzksaPux7PyqFnbc/6fye3Fc0FsCvdJaHztflq753plJYl9luvTrvfs191O11h6qAdfrf9vX5r773o5LYX0J+o/N7m39tb3fZ3Op7nyqFdfr9Lh/3Dqf9d+UXGv/7DVWi8yPgUT3u53zuT7VQXAC/6v5x6/q4VCP2Hzar2Pi5lu+TuY9IO3OxzX47f5e6j6Z871clcN9FtU7Xdt51Jek/ve5QBXG/iNi12tB1X+OnJdbxWVuY/sD3flQSd+CH+657593wXXdN/1664med/tl9Z9O6vuZ7f0AQ9gXzHfcuoNvu/A/tFt/7VA20FkD3j9vgwYPPdNvuSG7f+1MpnJf1edBtu3VzX0q3m1/zvFsVR9s7gLYA/l3XwQP2dfmH1u9p3/tUKToP/Hiq8+7X7fabXneo8rjvyv23vf2G7x2pJHadRlqvv+9x3x0EouJjYFtsG6zPLW7bzZ29P8P3PoEw7ItmeefHbCu1nbbB4b4nYYdkr81d7ovcvvenUnS+2/Jz69XRmTt971OlcKXWndqg83W5zv2W63ufKo07zY17x929YzZw4MDf9b0/lcJ9H9V9qmDX70ot79p20Xm6jSnWb6775dn3/lSSQYMG/bZ1avW9H1XgG+5UZ+7AFvfa1HJ0s8N93OteizYXOUff+wMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA//j9w9VzVhgglEAAAAABJRU5ErkJggg==\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Or a (X, Y) point series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(x, y)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nO2dX6id+V2vp53pHEmnaDXbyEpOkr3XH8W2FIUZiEopomD9W6YynVBba0jtKaWCSk07pR40JQShFx3bUU+OVC/EC4nVFC8Uab0T9WBPRXrAGyVpclG3XvScU8GLzvn+nLUOm3IOWRfr5buej88DT9f7rp28vA97fdPv3nsl88gjIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIsVyuXx3+c7yQ4vF4tx4rh6v1fnT5fXNcyIiIiISQC1331lL3q+N44ODgyfq+HfruUur1erWeK4ez9Zzt3vvUkRERER2Ri13768l74Mnzr8wzmsJvHriuXs9dyciIiIiO6cWvfeUv7g5r+Xvn2rh+83y8ua5Or47vjvYc4ciIiIislPm8/k314L3G+P46OjodbUA/q/yv9ZS+Mzm19T5g9lsduph1/rqV7/6ooiIiLCYcs+QPWYsfrUE/nA9PlnL3l+ufwR8ZfPxOr+/zXXGi+j4+Msv/uM/ZjmabONpG9fkPtuYprdNt2HI3lKL3ryWv18fx2MBrPOfHY/13Avr5+pweWeba43hGC+mL30py9FkG0/buCb32cY0vW3KPUP2lPGj3Vr6PlD+xPinXzbP1/GN1Wr1bHlzPp8vtrlW8nDYxtM2rsl9tjFNb5tuy5B/FyQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1B4CQPh208beOa3Gcb0/S27v1Bmlgul98/n8/fulqt3rVYLF4znqvHa/X80+X1Oj63zXWSh8M2nrZxTe6zjWl627Rbhuwlp0+fflUtee/bnNfxR2rhu1TL4K1xXo9n67nb21wreThs42kb1+Q+25imt021Y8h+83gteX9zdHT0urNnz35TLX/vrfPn6vHq5hfUAnhvmwslD4dtPG3jmtxnG9P0tulWDNlrxo9/a8n7SvmHdfp4PT5fXt58vI7vHhwcPPGw64zhOD5+6cWU5GiyjadtXJP7bGOa3jbpkiH7ycWLF79u/Ni3lsDvqse/WCwW/2W1Wn28Hp/Z/Jo6fzCbzU497FovioiICI5pNw3ZS9Z/8ePS+vTRWgL/rJ77YD135cSvub/NtcaLKPWrI9t42sY1uc82pultkywYst/UwvdTteB934nzjxwdHT1Zjy+M8zquw+Wdba41hmO8mLrfz+B7P2yzjW1yn21M09um2jFkv3ls/JMv5dvHX/wYy994so5v1GL4bHlzPp8vtrlQ8nDYxtM2rsl9tjFNb5t2zZB4kofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iBwkofDNp62cU3us41pelv3/iANXCxWq9UvnTlz5pUnn18sFteWy+XT5fU6PrfNtZKHwzaetnFN7rONaXrbNBuG7DW13L2xlrx/qSXwn8t/qOMvlm+o41vj4/V4ts5vb3Ot5OGwjadtXJP7bGOa3jbtpiF7SS13b6mHx8fx6dOnX1UL4dtr6XuuHq+e+DX3trlW8nDYxtM2rsl9tjFNb5toxRAKtei9vx5eVo/Pl5dPPH/34ODgiYf9/jEcx8cvvZiSHE228bSNa3KfbUzT2yZdLmS/qSXvhxaLxY+O49Vq9Yk6fmbzsTp/MJvNTj3sGi+KiIgIjin3C9lzasn704sXL37L+nj8CPjKiY/d3+Ya40WU+tWRbTxt45rcZxvT9LapdgvZfx6vJe9f6/GxcVLHT43vAo7jo6OjZXFnm4uM4Rgvpu73M/jeD9tsY5vcZxvT9LYJ9wvZZy5evPgNtfD9/cnnFovFjXru2fLmfD5fbHOd5OGwjadtXJP7bGOa3jbNdiH/bkgeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDwEkeDtt42sY1uc82pult3fuDNHHhwoXD5XL5kfl8/tbFYvHMeK4er9VzT5fX6/jcNtdJHg7beNrGNbnPNqbpbdNuGbK3rFarzxwcHDwxm81O18L3R7XwXarnbq0/draeu73NdZKHwzaetnFN7rONaXrbtFuG7CW17L2xlrxPnXjq8Tp/rp6/unmiFsB721wreThs42kb1+Q+25imt+18uZD9p5a9n68F79O18P1IPb57Pp9/dz0+X17e/Jo6vju+Q/iwa43hOD5+6cWU5GiyjadtXJP7bGOa3jbtpiF7SS13v1B+dn368jr+XC2FH9+8F3BQ5w9ms9mph13rRREREcEx2ZIh+0std8/Wsvfbm/Px3b7yw/XclRO/5v421xovotSvjmzjaRvX5D7bmKa3TbFfyJ6z/osff7w+fbSO//ro6OjJenxhPFHHdbi8s821xnCMF1P3+xl874dttrFN7rONaXrbZEuG7De14L2zfN9isfjAarV6ajxXxzfGdwfLm/P5fLHNdZKHwzaetnFN7rONaXrbtFuGxJM8HLbxtI1rcp9tTNPbuvcHgZM8HLbxtI1rcp9tTNPbuvcHgZM8HLbxtI1rcp9tTNPbuvcHgZM8HLbxtI1r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PtuYprdNtVzInlML3rsODw/PjOPxN3+Pjo6erMcXxnkd1+HyzjbXGcMxXkzd72fwvR+22cY2uc82pultU+4YsqeMv/lbC+CXa8n70tpPjucXi8WNev7Z8mb9msU210oeDtt42sY1uc82pult024aEk/ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fBE7ycNjG0zauyX22MU1v694fpJHVavXTR0dH37M5XywW15bL5dPl9To+t801kofDNp62cU3us41pett024XsM4/XgvfeWgD/qpa9N4wn6vxSnd8ax/V4tp6/vc2FkofDNp62cU3us41petuUS4bsObXkfXKzANbS91wtgVdPfOzeNtdIHg7beNrGNbnPNqbpbVPtFgLg5AJYj8+Xl0987O7BwcETD7vGGI7j45deTEmOJtt42sY1uc82pultU+4Xsud8zXcAP7FYLJ7ZfKzOH8xms1MPu8aLIiIigmPK/UL2nP/Hj4CvbD5W5/e3ucZ4EaV+dWQbT9u4JvfZxjS9bardQgB8zQL41Pgu4Dg+Ojqqp5d3trnGGI7xYup+P4Pv/bDNNrbJfbYxTW+bcr+QPWaxWLynlry/LX+rjt+4fu5GLYHPljfn8/lim+skD4dtPG3jmtxnG9P0tkmXDMkneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt2PyCAUAAAfySURBVHXvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvDwIneThs42kb1+Q+25imt3XvD7JHLBaLa8vl8unyeh2f2+b3JA+HbTxt45rcZxvT9LapdwqBUAvfpdVqdWsc1+PZWgJvb/P7kofDNp62cU3us41petu0W4VgqKXvuVoCr27OawG8t83vSx4O23jaxjW5zzam6W3TbRSCoha+58vLJ87vHhwcPPGw3zeG4/j4pRdTkqPJNp62cU3us41petu0W4VgWK1Wn1gsFs+cOH8wm81Odd6TiIiIiEzI+kfAV06c3++8HxERERGZmFr4nhrfBRzHR0dHy+JO9z2JiIiIyMQsFosbtQQ+W96cz+eL7vsRERERERERERERERERERERERERERERERERERERERERERERkf8vi8Xi2nK5fLq8Xsfnuu9nClar1U8fHR19T/d97Jr6fL1n/Hef63P3O4eHhxe672eXVNfbqust5cfq8/eD3fczBaMtbebqc/X6enh0/Ocn0/4JqgsXLhzW5+wj1fXWk/+1JToXi/q8/dKZM2de2X0vU1Cfs+8fn7NqfFc9vrb7fnZJtb27fGf5oWr7j933IyDqD7FLNRS3xnE9nq0X0e3ue9oxj1fje6vtr6rtDd03s0tq2N+0+cOsHt9cfZ/uvqddMf6Ptj5nnx/H1fYD4/PXfU+7pl6X31Gfs7+rL0zOd9/LLqmmz9Xn67j81Gw2O919P7ukmj4zFtvRVZ1/1H0/u6Jei2+snn+pvn8u/6GOv1ivyye772sXnD59+lXV877N+VjgO+9nl9Tn7Tur59fG8Xhd1vHvdt+TgFj/Z+Oubs7rBXSv836moro+mbYAVs/P1OfuV8dxPX57nf/37nvaJefPn3/1eBxf2VbfL3bfz44ZX5j82Fgo0hbAanpH9z1MwViSxlJ74qnH225mx4zvtD+y7hkLU7W+vfmWdsnj9Xn7m5qz1509e/abxjcEum9oV9Tn7f3V9sET51/ovB+BUS+Y58vLJ87vjq8kOu9pChIXwOLR+kPt68fB+sfAv9J9QzvmFePHNtX1m48E/Z/toD5fP14Pj1XbZwMXwPFfH3rT+D+mixcvflv3/eyK6vn58V32+tz9SD3+p2r87u57moKxVNTDy7rvY5es/xz5SvmHdfqK7vvZFeu3AP3fL47rNfpPY4HvvCcBMf6bwSffy1LnD2az2anOe5qC0AXw31j/iOP3U9+/s/5PGv5B933sipq316zfJ/dI4gL4yHp5WL8u/7z7ZnZFtfzC+HytT18+ftTdekMTUE0/VK/PH+2+j11SX4R83fp9m99Vj39R/kb3Pe2KavrmTc/4Dmf9ufI/E///WyZi/SPgKyfO73fez1QEL4AvG3+4bX5cmkj9wVaJy6+mvJ9s/Ih07U+W/6Pm7+fGj6a672sXjPeiVtNH16djSfrfrTe0Q8YXIvW5+u3NeeJPS6rxT2th+pbu+9gl4y9+jPe6r0//7bvuSX9ejsWvmn54vGezWv+y+34ERL1gnhrfBRzH6/+jvdN9T1OQugCOP9wODw/PjOPxN7m772dXjK7q+b1xPD5v403pdfjy5tvaOWnfAawF8Hs3f3mgXpffWn1/0n1Pu2L9Fz/+eH36aB3/desN7Z7xXrl/rcfHum9kl9Tn6aeq6/tOnI+/BBLxY+BabOfV8+vjeMxdnf9s9z0JjHrR3Fj/mO1m2j/bMBjvk6gh+dvyt8YbubvvZ1esv9vy5er60tpPdt/TrhhL7finDdavy1vjq9zue9o145+5Gd9xH98xO3fu3Dd238+uGO9HHT9VqM/fL6d813bD+p/beF/1fWB88dx9P7vk4sWL31BNf999HxPw2PinzsZfbBmvzZS/3TwYP+4dr8XyJ0Zj9/2IiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIjsH/8H9QLawsZ9m/IAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Plotting a discrete (X, Y) point series, as we would do with matplotlib\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" y = [i**2 for i in x]\n",
|
|
" figure.plot(x, y, \"x\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# But we can also plot a function, by automatically\n",
|
|
"# evaluating it on the given interval\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, (-2, 2)) # Plot sinus on [-2, 2]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# We can also do the same forcing replot to use some evaluation points\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = np.linspace(-np.pi, np.pi, 200)\n",
|
|
" figure.plot(np.sin, x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# And we can plot multiples graphs on the same figure\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(range(5))\n",
|
|
" for i in range(8):\n",
|
|
" figure.plot(lambda x: np.sin(x + np.pi * i / 4), (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Advanced plotting\n",
|
|
"\n",
|
|
"We can do more elaborated stuff easily with `replot`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Plot with a label on the axis, and a title for the figure\n",
|
|
"# Note how the legend will be automatically added when a \"label\" is found!\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" x = range(10)\n",
|
|
" figure.plot(x, x, label=\"x\")\n",
|
|
" figure.xlabel = \"some x label\"\n",
|
|
" figure.ylabel = \"some y label\"\n",
|
|
" figure.title = \"A title for the figure\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9B5hcR3YeusGW/WQlP5Nem5tAYGa0lp/kKPnpe5Zs61mWZEufFd5ylwmZiEQiApEBIudEJCIRgQAIEDkQOeec4/RMz3RuECB3V9ogacl5daruvTMYTM909w1/1b3n/74fkxp9z71/V9WpqlPnfOlLDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMhseoqqr668rKyt9v4zXxioqKrm6uI64xVzAv3utH4r3+tZv3agvi/f+LuNYX4tuvePm+4j3/UNh/X3z9ofg6VXx9RXy95+U1GAwGg8FgMFqFcEC6kKMjHJ4pbb1WOCqdxGuTrb2mkOPk1gEU//f/Fu/7s3bt2v2Lct+jEMT7vi/sW9vsenQfn3/JYweQnD/x3m95+Z4MBoPBYDAYJUE4JBeFo/NIMCd+/IetvVa8prNgorXXCOfmv1qO01ebXcetA/haW9cuAi3eX8AO4N936NDhD7x8zyLQqq4MBoPBYDAihPbt2/9HcnKEs/M/aHWNtiNbee1/Fn//qeDPacuXtmHF9y/T32jFj5wawW+K739C72m/Rrz3cHpNcwewXbt23xGv202OJ60qir8veuGFF36xpWuLv41vem3x9ZZl06+K91xG/99yYveK31XZ/0/8bZx4/Snx+wnia1p8vd3Ce48Q/DvBv21i8zdsB1Dwr8TvHtCWreDBb3/72/+yyfv/I1o5Fb+Pidc8EV+PC/7bAs+v0rKd3vMndB3xvP6f5quqzz///C+Jn1eL3z8mh1ewv/V8OlrXfGaFtfl7WA7tJvF1sf1c6Pff/OY3XxDfrxdMWc99vXjmzxXSnMFgMBgMRghBjoLgFev7jcJpON3a6y1H45lVONsBpO+brJx9udn/dRzAr3/96//Mckz6ix//wTe+8Y3/k5wrwfdKuTY5kOL3R8T7Pi8cyn9sxQgmbEfScgD/TvxulPjxF+g1hZ5DgRXAL8Tv15FT9txzz/0yPR96bZP/t7qJU/gV8X/6UIwiOaaF7sN6Vv+t0H2J71cJnn/xxRe/RvaKvy+3nNOmDuBTK5MtvMf71v/pJH78qnXfv0CxhuJv0+lnekbivdaQ/YVsZTAYDAaDETIIJ+DXxOD/Y+EU9KCfySkhx0I4L79Z6P+U6AAWjAEUXwc1dzZpNYxWIb/UzHEsdG2KBbSu+381edk/EK/7RLz/S9Z1xrUVs2jZX3ALWPz+601+Rw7eHfrecmLp+hXN3uthayupTZ9VC/f1ZXoG4jp/ZP+dHE9r5bNUB/BM0+uKn/+i+bOgeyN7aGWwtefDYDAYDAYjJKCDCLQlSatb1q++bDkvSwr9H68cQNqatFaoPrUpfvcDckibbrG2dm3hqP42Xaf5trF43WXx+yGWLePaWtW07CkqBrCpDeL737FWCJvew2fi69+Ir8NauVZBB1D8/p/T3wX/VbN7+qRUB1Dwg2bXHUbxh83tpWdOB2zaekYMBoPBYDBCAIprs5ywjGCWaK0I/qiJU/gUhKPwelsOoPj/v1fECuBY8fPhEu1taQWw+YrlV2lrWbz/d63r0ArgybbeW7xmZakOoLjutypV/OQ3SrmPYlYAxd//uIkdv9JsBfDf03VpZbDJe4xsYQXwqfuh/y9+X12KrQwGg8FgMEIE69AHHUb4fVp1asIKWhUUf+/b0v8Tr/9DOsBAMXvNfu84NXTYwXKMfqPpa5o6gHRYhA5N0JaqeK//w/6d+Pl/F7K5UAwgxbCR7fQ+4jWzaZvza1/72j+x7rMoB1C8brK1ZfqVJr8rZqVtq+BOcgbpZ3LKyHmj+L1C12rDAbRjAM+Sg0urm+L7pU1jAK1DIj+wVjnJYfy39GzbcgDp/4nf1Ym/TSCnkn5Hz83eLmcwGAwGgxFyCCdgm+D+An+jgxTPnJa1QCtsdFjksbWN+H3r/3ze1KmpbEzY/Km9HSq+r216CphO65IdtAJpbUXetg5rtIiWHECKY7ROAaesbdKPhfP16/bfi3UAxf/5NjmA9tZo01PAX2rFAbROAY9tckqYTtduaS1XYfNn1fw9m5wCplPFdLq5n2CuqaNGjjKt5lknsffSSeu2HEACba9XqoMr9ZYT+VD833fbej4MBoPBYDAYjABhHdah1dr/hLaFwWAwGAwGg+EDrFyKVFbvK9ZJY1pxpVJxniakZjAYjFCAUllQotrWXlNRUfG26Ez/UnBiqYHbDAaDEQRE39RB9Gc3KlWtYEoGTcmtK9F2MRgMhm74BQpYFx3lpcpWitGL1/wuJVSl763cV1uDM5HBYDAYDAaD4TmsvFcFHUBKkyCcwO5NXt9mclgGg8FgMBgMhsZoywEUf1tQadUttX5OFMp1xmDYuPX9//3Nh52+9351p5euPOz4UvJhp5e23Ov43d9F28UIJx50/O5/ru740jLxmUtXd/ze7QedvreiuuNf/Tu0XYxw4v7r3/0D8Xk78rDj9+6Kz9w90c/NutfxL/4Z2i4GoyQUsQK4qGkaBUo9UajwfFN88cUXDYxo4ofHjzTEenZuqO70vWeYX7m04YvPP0ebyAgJqJ95snNbi5+16m6vNvzg6KEG7osYXuHzn/20IfPu7BY/bzW9Ojf89YVzaBM9gVf+BUNzFLkF3LXJz+li3pc+RI8f/6jhk0+YYSfpbOud2rvP6RDrFy1oyN2635CP1TckN29uiPXqon6/cEHDo/wP4HYz3euNtOPRox821C9doj5vXV9pSH64sSH3oFZ+5hKr33c+h4l16+DPzGTqojeaj3KfNcSnTZafqVjvbg2pHTsb8tV1Dbkbdxvq5s5Sn7curzRkTp2F2+pWby98C4YBaO4A0km6pn+nup20CkjfW5UKdhXzvtRhyEbziBl2ks6E7MUrciCmjjB14NAzr8tevdVQbTmBNCij7Wa60xvdvlO79qhBt2fnhszZC8/8PX3itFwFpNekT5yBPzdTqYveaNYvXqScv/49xUQj/szfk5s2qc9j99cbMlduwO11o7e3XgZDSwhnr7dVRWC1+P6/fkmVR4rZ5Y6avG4KVS4QnEYlr4p5b+4wokPS+ed/89cNsb7dlXO3fkPB12Yu32io7vx9MTC/1pB7WAe3nVme3uj2nb0bkwOtdO5Oni34OttJjPXu2uKgzTRDbzQzZy44k43sjbstviaf/2FD/cqVajt42KCGfPZTuN3l6u2Hv8GIEKLeYUSJUuf1q2XHR1sk1BG29np7Jl23YB7cdmZ5eiPbdz73g4basSNVOMF7S1t/rfgs1s2boz6bM6fBn52JROuNJn2GaseMkJ+h5I6drb82+1lDzYgh6rWbP4LbXq7eaP+BYTii3GFEjbk7D9TWryCtzLT5+liyofqNjnIlMHv9Dtx+ZmlEOwTpw8fUKsvgfg351Cdtvj5fn3PiTzOXrsGfn2lE641m+vgptYo8sE9DPtP2qh59xuytYBNXndkBZLhGlDuMqDE+bZLa+n1/VdH/J/HBB2pVZtI7cPuZpRHpENDqX82wgSrO9ODhov8frcbQ/6l9Z0ybK9RMffRGU37erBU9OuBW7P+rW7xQrVAvXQK/h3L0RvsPDMMR1Q4jaszeeqBWY/p2b3iUzBf9//LJRw2xN3uoGK5ThWO4mPoR6RCQ06dirAbKwbnY/5dPP26I9e9lxQzygRBT9EYzfeio+rwN6S+3d4v9f7n7tSrWuUenhnziEfw+StUb7T8wDEdUO4yosX7lCtlBfrJxXcl6p3arAP2at98qaTBnYolyCGjlrmaoWv2jgbnU/5/cuduJU0U/Q5MYVQdQrv4NHVDyarNNO2VMcucu+L2Uqjfaf2AYjih2GFFjPvNE5sOiTu5vM+mS9ZYB0/Z23v6D8PthFkeUQ5C5eLUx9q+MCQOtxMiTw11elnGo6OdoCqPqAKY+3u9qgkqph+T/Hz7YqLADdgAZrmFyh3Hy5IWG3r3fhNuhO1MHjzhxVeXqbb9HfNJ4+P0wiyPKIahfsljFmm4onGaoLdLJc5NPaEZJbyTl6t9bb6rV5qMny36P2KC+6vDRhavweypFb7T/wDAcUeswosjaieNVB7n/YNkDBMVmVfdQJ4J5VcYMIhwCudpsneSl+Kpy3ydz7lJjDKFBqzJR0xtNZ7V5qLvPSXLTZpXyat4c+D2Vojfaf2AYDlM6jGTyk4bevfs2/NEf/XHD//pff9rw2mudGg4cOCa/p7/fvPmg4d//+//QMHXqzIY/+7P/3fAHf/DfG3bt2g+3G02ZiJdSHYhB+VHmsasBom7+XLUqs207/L6YbRPhEKSPHFerzeNHu3qfp1ZlLptbrSHseqNZv3yZldR+vav3ydWmG6q7viqZq03B76tYvdH+A8NwFNNhxGdNdxqH16T3LubDvmXLrobXX+/s/FxTk5YO4J/+6Z/Jn8kB/PVf/3X5Ovp59+4DDf/9v/8hvJGimVijEj/XL3vP9QBBlRzk4D5mBPy+mG0T4RBQEmcZK7p7j+v3slMQ0ZYy+lmawKg5gHKS0K+n/Ixkbz9w/X72BDfx4Sb4vRWrN9p/YBgOUxzA69fvNfz+7/+XhuHDRzVs3Li1oa4u94wD+Fu/9VuNNsczDb/xG78Bb6RIUokjO4VL9vpd1wOEfL8+6jBJ7l4N/P6YrTNohyBXl1WJxru9KpM6u34/StFhlfXKp5/An6fujJoDmDl/2Tm84cn7XbzWmEjagGwH7AAyXMOkDiOReNSwffvehpEjx0pnkFb7mjqA/+E//EfntfX1+YbvfOc7cJuRTB89oVbsRg93Ogy3elPCVDlL3rgRfn/M1hm0Q0BpNORBodkzPHvP2onjyk7vETVGzQGsX7bU075Ipi8SzmRbdat1ITuADNcwpcO4cycmHUD6PpP5VDqAS5Ysf8oBpBhAp3MQDiBtCaPtRtKu/JHavdfpMNzqnblwxSmijr4/ZusM2iGw6/6mj5V3GrMlpvYdVE7lZK5Eo5veSMrtX3t34061Z++b/GiLMZVB2AFkuIYpHQYd6Pif//NPJf/4j/+kYcqUGc9sAfMKYCOp9qq9zW5nuPdigJAd74DequO9cRd+n8zCDNIhsA8bUb7JYuqwFkv5Oe7RSZ0+f1gHf6Y6M0oOoHNKfORQT983e/th4zaw5qfP2QFkuEZUOoyo0S6M3rSGr1cDRP37q9TWy+rV8PtkFmaQDoFzYOO9pZ6/d93CBXz6XDO90XRCUTw+sCG3ga28gtmb9+D32ZbeaP+BYTii0mFEjTQQy0Fzy9anOgwv9M5eu23MLDnKDNIhsEtxZS5f9/y97dQyFNKAfqY6MyoOIFUmivXtrpy0uzHP358yJpiQhJwdQIZrRKHDiBrlLHaQNYu91ZgewasBommtVzo5h75fZssMyiHIPYirCcGbPXyZENCJYioLR+XhKNE0+rnqyqg4gJmzF9ThtlHDfHn/9KmzTuUk9L22pTfaf2AYjih0GFEjBUW3tELn5QCRWLdObcGIr+j7ZbbMoByC1J6PVRWF+XN9u0btuFFqwnH2Ivy56sqoOID1Sxb5ukJHKYfsWtRepDPyU2+0/8AwHFHoMKJGipVSCXQXPdNheKW3HYRNAzP6fpktMyiHoG7ubHXa/GP/Ku9QpQeOO9VDbyRpQhvr18MqNehfLtL49CnqRPuho/B7bk1vtP/AMBxh7zCiyPjUiS0WR/dygKCtODVLfqUhn3wEv2fmswzCIZCnwvuoeKxcdb1v16HYQj9OfYaJUXAAqeKH/BwM7ufrdZI7d6tV7QXz4Pfcmt5o/4FhOMLeYUSN+fTjRscs8bRj5vUAQbnZpKN54gz8vpnPMgiHIHv9jpUXcqCv9yIdzV5dlKNpSK3WMOqNZnKHSjZev3iRr9dx4lr7dte2Kgg7gAzXCHuHETU6AcwTxrbYYXipd3LTZtUZr1wJv2/mswzCIXAS5y5f5vv91M2eobaa9x+EP1sdGQUH0PkMBFAZpubtt1Tc6ZUb8PsupDfaf2AYjrB3GFFj/YrlKkBaOGctdRhe6p25clOt/owYAr9v5rMMwiGIT56gVoGPn/L9fqiije7bcmHXG0kVbmDVIo8lfb9eYvX7Ku70gw/g915Ib7T/wDAcYe4wosiaISofW/b6s1U6vB4gqEOutrfl4mn4vTP91fsZ/ZvGgSb8jwP1O92M6Qy7A0iVh+SEc6i/4QY2M+cvW7XU34bfeyG90f4Dw3CEucOIGulUnBwg+/VscYD0Y4CIz5ym/Wm5qNJvh4BSssgBcnxwJ8HthNMtTXCizrA7gE52g4Dq9FLCaWeCW6Nf3Ck7gAzXCHOHETUmd6oAaSqdVajD8Frv5PadVsqZxfD7Z/qvd1Mm1qwJfIuMYg1NqNIQRr3RjM+Yqiabh48Fd00r5lDHCS47gAzXCHOHETU6HWSBzsqPAYIqjQSRloFZOv12CGhrTFWDuRrYPdGJc1Xjejz8+erGMDuAT50CDzDcJLl1W2CHnMrRG+0/MAxHWDuMqFEmSLUDpGtb7iD9GCCeSsz6sA7+HJj+6u3oXpdtqO78/YbqHp0a8tlPA7unfOqThuqurzRUd3tVfo9+xjoxzA6gXX+cTuYGeV06Aexn2Tm3eqP9B4bhCGuHETVSUfS2VuL8GiCoBJhMzbB3H/w5MP3Xm0jbcHIlbvqUwO+LUhzJlcczF+DPWCeG2QEMMt1QU9LkxikLp9mEgx1AhmuEtcOIGqkMV1spMvwaIMjx87sWLLN0+ukQUMynjMXbtj3w+0qsXatiDzdsgD9jnRhmBzA+bbJV3ehE4Nd2Jhya1aFmB5DhGmHtMKJGZ0DeubvVDsMPvZ30HAVOHzMx9NMhqBk2SJ3GvXkv8PtKnzitVh+nTYI/Y50YVgdQnsbt2VmGHFDoQdDXT6y1Djtt3Ah/Fs31RvsPDMMRxg4jiqwZPlgNyDcKp8fw1SEY3E9d//ZD+LNg+qt3PpFX8X9iUEaUycrFM2rC0bsbTzgC0BtNOw4PVQfaOXg0dSL8WTTXG+0/MAxHGDuMqNEZkCkgv5UB2c8BglLPcBygXvRLb4q9Q5/EdSYcd6rhz1kXhtUBRJeclAeexPUpJ6BOdYHZAWS4Rhg7jKgxc/q8NSC/02aH4ZfetPUcZJJWZtv0S2/aCpNbYmvXwO6NYl3lhGPfAfhz1oVhdQDjUycFVm6wEJEhD63pjfYfGIYjjB1G1JhYv14NyOvWtdlh+KW3naZBx3QJUaVfetPJX/SAnNyxiyccAemNZqzvG/Byk/WLF7UZY43QG+0/MAxHGDuMqDE+ZaIakE+dbbPD8C0vnJMu4ZWGfPoJ/Jkwfcz7aA/ItbjyWE5eOFBcmI4MowOYiyVUvOeA3lA7ismygNAb7T8wDEfYOoyokWJS5Ak50Tnl63Ntdhi+VoYYN8qqDHEN/lyY/uidu1+rBuRBfaH3Jk+GapqfLUx6o+kcwADkm2xKJ8/qW2/Cn0lTvdH+A8NwhK3DiBopJkV2TMMGFdVh+Kl3/Yrlaptk6zb4c2H6o3fq4BG1EjJ3Fvz+at8ZoyYc5y7BbdGBYXQAKddj0PWmW6Ja+e6uVr5rcCvfzfVG+w8MwxG2DiNqTO3eqwbkRQuL6jD81NtxDubNhj8Xpj966+TkJ1avVrZs2gS3RQeG0QGMz5yuwluOndTAlmnKliPH4bbYeqP9B4bhCFuHETWWkn7F7wEid79Gu22SKNMPvWvHjlSrbpfw2/zpoyfV9uCMqXBbdGAYHcDYwD7a1BlPbv7ISkezAm6LrTfaf2AYjrB1GFFjzdABVgLmB0V1GH7qLbdJ+nSzTuxl4M8m6vRa73zm04bqbq82VHfV46APbcXJeMS+b3BCaB/0RtPOv0d9ig76UmyzzHQwZgTcFltvtP/AMBxh6jCixpzdQfbuWlSC0iAGCCdn18nWTyQz/afXemeu3FQD4Oi34fdmkw6jyAnH/Vq4LWiGzQGk2rvF5DcNivnMkyYToMdwe9gBZLhGmDqMqLGxRFFxNVGDGCCcnITiK/r5RJ1e653cvkNtgS17D35vNuvmzlYhEAcOwW1BM2wOYPKjLerz9v4quC02nRCIyzfgtrADyHCNMHUYUWOpRcqDGCBo5a8Up5TpH73Wu27+XOVs7T8IvzebyW3blZOwfBncFjTD5gDWzZujPm8Hj8BtsUmJx1VC6F1wW9gBZLhGmDqMqNFJAH36fNEdht96U+yfTnE7UabXejv1d+/G4PdmM3PlhrUtPRxuC5phcwBrhg606j0/hNtiM7VHZV2gyiBoW9gBZLhGmDqMqLHUEklBDRB0CljFZdXAn1GU6aXejmPfWy/HXh1MeU2bgylh0RtNSu5d3fn7DdU9OhYV3xwUs1dvaVPykh1AhmuEpcOIGp0SSf17ldRhBKE35QHUbesmivRS7/TJ0uJNgySdypRxWVduwm0Ji95oUpoh6WiNHwW3pSnlQRAx2aDDIFT+Eq032n9gGI6wdBhRYzklkoIaIChJsNwmWbEc/pyiTC/1pkoMuh7useOyKCk62paw6I1mcsdObWM7qf603Jq+fheuN9p/YBiOsHQYUSMd/JAD8rp1JXUYQejt5Msap9fsPWr0Um+aaKj0Pmfg99WcqV17lLPw3lK4LWHRG02qbFRsgvvAbbOT73+8H6432n9gGI6wdBhRY3z2jJLLEgU1QFAsVnWXV2RsFnqbJMr0Uu/YgN4qrjOWgN9Xc1JKDp5whMsBbFxluwO3pTmT2/VYnWQHkOEaYekwosbGgxbFJ8ANcoBwOvAb2G2SKNMrvZ2E4326a3UAxKauBwZM1RtNmjRWd31VUscJZObiVSs+cTRcb7T/wDAcYegwosZ8Ii87oOpeXUoakIMcIOrena9dzrio0Su9M+cuaVWRoSU6KUM0SlFjqt5o0qqfLidtW2LjhKMTdMLBDiDDNcLQYUSNmfOXVQc5YWzJHUZQejsHQVbpk8U/avRK70YtV8LvqRDtiiDpw8fgtpiuN5oU90da1i1eCLelEJ0a7HeqoXqj/QeG4QhDhxE1OtUPSjxlG+QA4dTxnKzvqlHY6ZXezmruPn1Xc5ObNqtDUWvXwG0xXW80qdSgrLaxYxfclkJ0Ul0dwqW6YgeQ4Rph6DCixsYB+UDJHUZQejuJg9/sAX9eUaVXejvxnDfvwe+pENOnzqkJxzT98hSapjeadJhH5nW8dA1uSyEmN3+kJhyr34fqjfYfGIYjDB1G1FgzYkhZA3LQA0Ssf091UKU2BX9mUaQXeusekG8zV5OyEqP3hNtist5oUkxd9RsdZYwdxdqh7SnEzNkL8B0OdgAZrmF6hxE1ytJXZWaiD3qAoKoRpdQqZnpLL/SmU9ykIa0Cou+nLcb69bAmHMWVRgwbw+AAZm8/VJ+3YQPhtrTGxpPxuNKI7AAyXMP0DiNqzF67XfYJuaAHiMTq1SqW56Mt8OcWRXqhN8X9yYD8hQvg99MW41Mnqq3DiE44wuAApg4eVp+3+XPhtrTF2MA+asLxsA6mN9p/YBgO0zuMqNHNCbmgBwiTOvMw0gu961euVE781m3w+2mLiTXWhGPzR3BbTNUbzfr3VxkzaYzPnKZ2OI6dhOmN9h8YhsP0DiNqdHNCLugBInvrgdrOGT4Y/tyiSC/0jk8ar1bVzl2C309bpBOZcsIxbw7cFlP1RtOkz1tiwwZ1EOSDD2B6o/0HhuEwvcOIGmvHl39CLugBIp/9TMYqUswixS6in13U6FZvim2i6h/0ecvXZeH30xazd+z4sUFwW0zUG035eevdTX3e6nNwe9pi+sRpdRBk+hSY3mj/gWE4TO4wokZ5Qq5H+SfkEAMExSqqmp5cEi5outU7V51Qge4DesPvpRg6J0i7vNyQTz+G22Oa3mjmHsTV521QX7gtRdkbw7YPdgAZrmFyhxE1UpkrucIxdEDZHUbQetPhgXJyFjLd063e6ZNnoCsc5bB27Ei1Qn7lJtwW0/RGM330pPq8zZoOt6VYOivkgBVLdgAZrmFyhxE1pg8dVTFOc2eX3WEErbcJZcTCSrd6Jz7cpGKc1q2D30uxrF+6RE04du+F22Ka3mhSLJ38vG3cCLelWNa+MwaWtJodQIZrmNxhRI2JtWvVAZBNm8ruMILWm4K55ax+EpeEC5pu9a6bM8u4+rqpXXvUhOO9pXBbTNMbTVpplp+3k2fgthTL+iWL1YRjz8cQvdH+A8NwmNxhRI3xmdNVB3n8VNkdRtB65+2EqX27w59f1OhWb6fg/d0Y/F6KZebyDZUnc9wouC2m6Y1mrH8vlVcvloTbUiyduuwrg9/hYAeQ4RomdxhRY83Qga4GZNQAQUHSsmOv4ZJwQdKN3nTIiA4b0aEjOlyBvpew243WG02q3iIniv3Mqh2eOWOVhJsafA1qdgAZrmFqhxE1ypqsXagE3GtlD2yoASI+zSoJd+oc/DlGiW70dlbSxo6E30eprBncT004HsThtpiiN5rUN6AcKTd0TgIP7APRG+0/MAyHqR1G1OhFUmXUAJFYsybSFRpQdKN3arcVS7d0Cfw+SqUTS3bqLNwWU/RGk+Ka5QGQtWvgtpRCyl1Y3bOzOglcRmout3qj/QeG4TC1w4ga00eOWyeAZ7nqMBB6R71CA4pu9K5fvqzsijNoOuXEDChfp4veaNbNmamcdtHPoW0plXbqoezVW4HrjfYfGIbD1A4jarpXHj8AACAASURBVKTUCHKGvH6Dqw4DoXf2trV6+fZb8OcYJbrROz55gjEluZrTrpddv3gR3BZT9EbT2ba/XwO3pVTWLXrXynV6MHC90f4Dw3CY2mFEjbR65jYlB2qAkBUaur0mYxgplhH9LKNCN3qbfHAnc/m6il8cPxpuiyl6I5lP5KVe1b26yC1VtD2lMvnRFjU5X7M6cL3R/gPDcJjYYUSRNSOHqm2Gm/dcdRgovSl2Udp/+yH8WUaF5eqdTz5Sge2GDshUlUHa36cb3BYT9EYzc/6yctgnjIXbUg6dijkzpgauN9p/YBgOEzuMqFGuoHV/XdU4zZS/goYcIJykwkdPwJ9nVFiu3hTLZOoJYJuxfj3VCmY8DbdFd73RbMyltwJuSzm0axjXDOkfuN5o/4FhOEzsMKLG3P1aq4MprwZw0w4DpbdT5unD8qqYMIPTO7X/oDq0s3AB/B7KZe3E8SqG8cIVuC26641m/ZJFKoZu7z64LeXQmaB3/r6YoD8JVG+0/8AwGA86fvetzw7sNa7DiBrTJ7zZYkAOEKmD1kngBfPgzzMqLFdvp+SgwWl76pcttWoC74HborveaNLWL6qermf3MGqYCnG5cTdQvdE+BMNgPOz4vU9o1vIowFkLs3R6FWSMHCCy1++obcUxw+HPMyosV+/4LHclB3VgcsdOta24YjncFt31RjP2Zg+VR68uC7elXNbNn6smHIeOBKo32odgGIzqTi9dkXEyt+7DGxCzlc7FozQDyAEin36sSnT17GzkwQITWa7eNcPclRzUgZmzF9Wq+ZSJcFt01xtJ58BO3zfgtrghhbbISfoHHwSqN9qHYBiMh51e2ihn+sc4MF9nepVoFD1AxAb1tYq9J+DPNAosR+989rOG6q5UcvBVo2vp5mJJWIkuk/RG00nZ884YuC1umD56UoW4zJ4RqN5oH4JhMB50+t47KtZnM7wBMVumLDXUq4snpYbQA0R86kQV63P2Ivy5RoHl6J298zAUSbu9bDemEN2+y2Hq4/1qq36J2Um7s3eqVbsZNihQvdE+BCMAVFRUvF1ZWfmXghPF998o9Lqqqqp/I7589fnnn/+lDh06VLT1vtWvfe9V2fgWvQtvQMyW6eVKBnqAoHgsU8uLmchy9E4fC34lwy+iSnSZpDeaidWrQ1G2T66cd3tVrp7T90Hp7amjwdAPwuH7XeHYLafvxdevCydwa6HXir9dE695LLj9hRdeeK6t937w6vd+O4oZ801i5uwFz2KZ0ANEatceNdtf9h78uUaB5eid3GTFMq1bB7ffLSmNjYyd3R9siS6T9EaTMhvIMKSTZ+G2uCWtmgeZ7J4dwAhAOHMjhRPY3f5ZOHnJVl7bsZT3vvbnf/5rcnXpTbMDcMPM5HbvTjOiBwg743980jvw5xoFlqM3pemRTtPBw3D73ZLS2Ehndu0auC266o1mzdABVg3gWrgtbukkuz9yPDC93fgWDAMgHL4Fgi83+TlBW7wtvVY4gNM6dOjwJ+LriHbt2n2nmPev7aeO4D9K5OQHiqkX69+z8pnt2ev6vR4/VgMEfUXcSz6eVtvZA3rDn2sUWI7elKZHrmJcvw233y0zJ06p7exZ0+G26Ko3ko9yn8r64FQn/FH+B3B73DK5fr3azv5wY2B6e+VnMDSFcOYWVVRUvNTk58wLL7zwiwVe/mX657nnnvtl4SieK+b9k5NVEs6f1sYaGPohNW2C1OcnD++jTXGNL774oqGmTzd5P5//9KdocxjNIPXp1Vmm6/n8Zz9Dm+Maf5fPKgdwxFtoUxgt4G8zakJYP3oY2hRP8NcXzqnJ09J3A7umBy4GQ2dYW8Bdm/ycbul1HTp0+HPxt9nWj18RDuCPi3n/3Iolatn6wCH4DIr5LJ0kqfVZT2aMBOQKQe04KzD/2i34sw07S9U7X5NQJxkH9oHb7gVpVUkG5nd5Ra42oe3RTW80M/aBo7mz4LZ4wdyteyqlzcihgentgYvB0BnCqfsdWgWk79u3by/8uspd9L1wCjs0fZ1wAP9A/P236fsXX3zx18XrDhbz/p/u2RF4AktmcaTM+F4mSaVOg0BfUffkJLWOSGA+kqXq7Rw4mhqe5Mk1wwdbgfkP4LbopjeazoGjkIw9+Qxtab8s6wIHkUOTdPba32BoCOHsTRFO4PetGD9K7/Jl4eDFxO9/pdnrutNqofjbhGJOARP++vIFaxY2G96AmE8zc/GqmlFOGOtZh4EeIBoD89fCn2/YWarezoGjlSvgtnvFoAPzTdIbzbp354fmwJHNxkMtNYHo7YvDwYgOfpZS2z5UzBrdeJhPkw5+yAF56RLPOgz0AEH1ZeUq06zp8Ocbdpaqd/0y68DR7j1w270irS7JCcfGjXBbdNMbzdoxI6xwkNtwW7xifOY0NeE4cToQvdH+A8NwfP63f6tqtPboxDVaNWP9ypXqVNm27Z51GOgBgurLBp0xP6osVe/aieNVpZYLV+C2e8XUoSNqh2P+XLgtuumNZFgrtVDKIVVd66NA9Eb7DwzDQR0GBX2rGq1JeANiNjI+dZIakM9c8KzDQA8QFBtT3fVVyaAy5keVpeod699T9QPxNNx2r5i9cTcyOxw6tO9imatJOSmh0LZ4ydSBQ2rCsXBBIHqj/QeG4aAOIz75HeVonL8Mb0DMRsZsx7w64VmHocMA4WTMvxuDP+MwsxS984m8GpD7dIPb7SXzmSdqh+ONjoEE5puiN5qZc5dUKMjkcCWFp+1sOeEYMzwQvdH+A8NwUIfRGPuzF96AmIq0LSIHrp6dPdua12WAiM+eoeJkjp+CP+cwsxS9M5dvNIS1LGTN4H5qIvUgDrdFF73RTO7creKbly+D2+IlnX47gJAqdgAZrkEdRmr7dtUYV62CNyCmYuNMcoSnHYYOAwSdAA4qTibKLEXv1Mf71dbV4oVwu71mfPoUNeE4ZX69Wa/0RpNKW8o+YMcuuC1es2bQm9bOTb3veqP9B4bhoA4jc/qsWo6fMRXeeJiKlCfP61gSXQaIIONkosxS9E6sXq0G5C1b4XZ7zfr3V6l727oNbosueqMZnzJRhR2dvQi3xfN7m6Zit9Onz/uuN9p/YBgO6jAoZ5E8mTl0ILzxMBX9OE2mywCRvXpLrW6OHQl/zmFmKXrT5E8OWifPwO32mqm9+9QOx5JFcFt00RtNJ7455k18s06knbQgJhzsADJcgzoMWTJJnsx8JfSB0qYwPnO65/mkdBkg8slH6sBBry6ceshHlqJ3zRA7gW0t3G6vmbl8XU043hkDt0UXvZHMpx97Ht+sE4OacLADyHANu8OoGTZQDQD3/M9gzmybTkZ5D/XQaYCg9A/y/mpTcFvCymL1DrqEVdDM1+esE87d4bbooDea2etWap7R/p+URTCoA1XsADJcw+4wGreAwh0obQLz2U9lAfvqbq95OiDrNEBw6iH/Waze2VsPVAjIiCFwm/1irJ+d4zADtwWtN5pOcu4F8+C2+EEnpVLvrr6ucLIDyHANu8NwAqU9qjrBLJ9+Dcg6DRCU/kF+3nbuhtsSVharN9XJDXs98NqJ40JX5aRcvdFMrF+vyvN9+CHcFr8Y69/L9x0OdgAZrmF3GE7d2feWwhtP1Jk+fMyXAVmnAYLSP8jP24rlcFvCymL1pjq5ckAWAzPaZr9I/VrY6hyXqzea1K/J3SYx8UDb4hedHY5zl3zVG+0/MAyH3WHQVpxMBTMpXJnZTWRiwwZrQN7geYehywDhVAKYMhFuS1hZrN5UJ1cOyIeOwm32i8ntO0M/4dCpfbfGmpFDVSWgWw/gtvhFZ4fDxzyH7AAyXMPuMJzajAP7wBtP1Fk3z5ohHz7meYehywBBdaf58+Yvi9Wb6uTKAfnmPbjNfjFz9kLoJxw6te9ClLXAu78uDx3R4SO0PX4xtWuPmnAs829HjR1AhmvYHQYFq9KxfDqen08/gTegKJNi/9QM+b7nHYYuA8RTn7fUJ3B7wshi9JY6vNFR6ZAJb7unfHNhn3Do1L4L6vAgruKbh/SH2+InKdZUngSeON5XvdH+A8NwNO0worASoDv9nCHrNkBQwXT5ebt2G25LGFmM3rmHdWpAHtwPbq+fdCYc4l7DOuHQrX23xPSpc2oldvoUuC1+kk6bywlHvx6+6o32HxiGo2mH4Ww9hjg4V3c6VVmGDPClw9BpgKh7d74KzD94GG5LGFmM3s6APG0y3F6/SXW15YTj6i24LSi90aQsE3Jr9P3w152P9e2uJhx1Wd/0RvsPDMPRtMNIfPCBClzdtAneeKJKqvwhB+SZ03zpMHQaIOhzJg+7rFsHtyWMLEZvZ0BeFf4BmWpPywnH/oNwW1B6o1m/dInSYO8+uC1+s3bCWHUS+OJV3/RG+w8Mw9G0w0gdOKTSj4iOEt14okqq/SudojVrfOkwdBog0kdPqs/bnJlwW8LIYvSuX7I4MgOy07bWet+2dKBu7bsl+u0U6UTH2d2z1ze90f4Dw3A07TBoa0SVsBkFbzxRpbNKsc/7VQrdBojs7Ydqu3v4YLgtYWQxejcOyNfg9vrN9PFT1ur6dLgtKL3RpJi4sFdksZncvkOtrq9c4ZveaP+BYTiadhhOCZu+4a6ZqTP9jFPSbYCQJe+6el/yjlm83rG+b/gap6QTs3djasIxdCDcFpTeSEalJrNNv1MPsQPIcI3mHYYzIIjGim5AUaPfJxV1HCBoMJYrAvdq4LaEjW3pTU6fmvC9Abc1CMoT9t1elXW2afKBtidovdHMXL5h7TCNhtsSBJ0T9m+96ZveaP+BYTiadxjUOOWW0JUb8AYUNfqdq0zHAYIOu8iT5yfOwG0JG9vSm7Z95YA8YSzc1qBI4QZyhf12+KpQ6Ni+mzL18X4V87t4IdyWIPhUSi8fJhzsADJco3mHUbfo3VCflNOZmbMXfd8y0G2ASKxZrU6ef7QFbkvY2JbeqT0fqxilJYvhtgbFujmzQpvqSsf23ZRRbOs1b7+lJhx3HvqiN9p/YBiO5h1GctNmTs0BolM+aPkyX95fxwEite9ApFYFgmRbelPqFzkgb9sOtzUo2qmuEhs3wm0JWm80o7jaTweO1D2f9kVvtP/AMBzNO4z00RNqQJ47C954osb6VSt9HZB1HCAo1IBPnvvDtvSm5M9ycDp9Hm5rUEwdOqL6t/lz4bYErTeaUYz3Tax+X/XpW7f5ojfaf2AYjuYdBtWflYGrI4fCG0/UGJ8xVQ3IJ8/68v46DhDOyfM+3eC2hI1t6U3B6XJAflgHtzUoZq/fVROO0cPhtgStN5KNJ/5fjdSJf8oBKHd1li7xRW+0/8AwHM07DCoIT4Xhq3t0lKdS0Q0oSqwZpmbIlK7Cj/fXdYCI9etp5QZLw20JE1vTO5+22vkb0WrndLpeTjh6dYHbEqTeaFIMnFxYePstuC1BMnP+sorrnvSOL3qj/QeG4Wipw4gN6qsG5FgC3oCiwqdTVHzmyzV0HSBqJ45XJ88vXIHbEia2pnf2hrUSNmoY3M6g2TjhCFcyYl3bNzF9zKr6M3sG3JYg6WdmB3YAGa7RUocRnzxBDcjnLsEbUFSYexBXM+Qh/X27hq4DRP17S9XJ893+lEyKKlvTm07BygF53my4nUGz9p0xqn+7FK7qJ7q2b6JThi9ihwtlbtceHeVqO+2uea032n9gGI6WOoz6Ze9ZA/IeeAOKCjNnrKzx0yb5dg1dB4jGkkkr4baEia3pndy0SQ3IH3wAtzNo1i1a6Fu5RV31RtMpcXngENyWoFkzYogK7bnlbe5JdgAZrtFSh+EMyKt4QA6KyZ271DNfsdy3a+g6QGROn1fO71T/nN8osjW9o5zvM6yprnRt38TasSN9K3GpO2nbWx7uO3bSc73R/gPDcLTUYaRPnVMD8vQp8MYTFVLBcJkuYMdO366h6wARxPZ3FNma3s426OXrcDuDprP9PTdc29+6tm/aBqVDN7LEZfIR3J6gmVizxpcE2OwAMlyjpQ4jd7/WKpo+AN54okJytuUsUTjffl1D2wEigAMwUWRrejsHIeqycDuDZlgPwOjavnO1aXUQYkBvuC0IpvbusyruLPJcb7T/wDAcLXUYzoDclQfkoEjOthyQ7/uXJFXXAULe/7DoJYn1m4X0dlKh9O4KtxFB+/6re3YOVQocXdt3YyqU8XBbIPd/4aqacEwc57neaP+BYTgKdRg1wwb5mpOO2UjpcHd9VdLPJKm6DhBEJwn2KX+SYEeRhfQOczLkYhnr3yt0uSd1bd/OCpgPyZBNYK425csKKDuADNco1GE4dRtPRqduI6yDuF8TyJa7rgMEkU4AyziZ7TvgtoSFhfROHz5mpYCZA7cRxdoJY1UM5MXwpILRtX0n1qxWbXvLVrgtCMpUMD07qxjI9GNP9Ub7DwzDUajD8LOGIfNpBnXoRtcBgpjcuVutEixfBrclLCykd+LD6KaAsVm32EoF8/F+uC1+642mcwr2+Cm4LShSvKncUbt5z1O90f4Dw3AU6jBSez6O9LJ9kKSTvyoP3gpfr6PrAEHMnL3AqWAC0jvKKWBshjExsa7t28mDd9vbPHgmsW7uLOUEHznuqd5o/4FhOAp1GFSWK8qBu0GScv/J1dadu3y9jq4DBJFTwQSnd2MKmBtwG1FMHz1hpYKZBbfFb72R9LMShkmkiYbs4zdt9lRvtP/AMByFOgy/AleZz5Kqf8gB+cwFX6+j4wBhk1PBBKd3rF8PFY8UwRQwNmkrLmypYHRs37lY0rdauCYxte+AmnAsWuip3mj/gWE4CnUYfgWuMp8lrXrJE4kP4r5eR8cB4qnnwKlgfNc76ilgnOcg+rSwpYLRsX3zTpL1HC5dUxOOd8Z4qjfaf2AYjtY6jNrRb6vYjRt34Q0orKTVLlr1otUvP1PA2B2GbgNEU3IqGP/1zl6/owaiMdFNAWOTdjfkhKM2HKlgdGzfUU8BYzMXz6iJV7+enuqN9h8YhqO1DoPSRMgB+fAxeAMKKynPoox9GzbQ92vpOEA0JaeC8V9vJwXM/Llw+9CkxLwqFcxVuC1+6Y2mX2XQTKRTDi/1iWd6o/0HhuForcNIrF+vTsp9+CG88YSV6ZNn1RbJjKm+X0vHAaIpORWM/3pzCphGUmmuMKWC0bF9cwqYRlLidbmjdv2OZ3qj/QeG4Witw0gdPKxWC96dD288YWVy23bl9Kxa6fu1dBwgmpJTwfivd93CBcrpOXAIbh+aTiqYtWvgtvilN5o1I4cqp+dWdFPA2PR6R40dwIBRVVWVFcy0RbSdpaC1DiN79ZaKFxo3Ct54wkpa7ZID8q49vl9LxwGiKTkVjP96144frbY9r0Q3BYzN9NGTaoI7ZybcFr/0RpJTwDxNWnX3ckeNHcCAUVFR8V+KIdrOUtBah5FPPFKBq326wxtPWBmfOlENyGcv+n4t3QaI5uRUMP7rzSlgGpm9dV9NOEYOhdvil95I5mpSnAKmCWnVXU44Fi7wTG+0/8AwHG11GDxg+Muawf3UScSHdb5fS7cBosXnwalgfNM7n7QmdL27wW3Tgfn0E7k6Vd2jUyhSwejWvjkFTLPnceWG2lEb782OGjuAWPxCZWXlRMEawR/SLyoqKv6oqqrqTbRhpaCtDoOrBvjHfPbThuouLzdUd3/d9xQwdoeh0wDREjkVjH96Z6/dtlLAjIDbpgtpdUpOOGpScFu81htNJwXMksVwW3Rgvj6nJmB93/BMb7T/EFkIZ+9d4eztE/w94QD+gH7XoUOHb4rvb6NtKwVtdRhO0fR90a0b6hezd6rVFtTbbwVyPd0GiJZIh2E4FYw/enMKmGdZO3G8muBeuAK3xWu90eQUMM8y1qeb2lFL5D3RG+0/RBZ02EM4gb9iff+p/XvbGTQFbXUYYSyargvTJ86oLZKZ0wK5nm4DREvkVDD+6U3B57Itr18Pt00X0uqUnODu3Qe3xWu90aTDNXI1/9hJuC26sHbsSHUq+uotT/RG+w+RhXD0kl/72tf+CX1vO4Dt2rX7NfF9HdSwEtFWh0GNV52UC0/RdF2Y3LpNOTvvrwrkeroNEC2RU8H4pzengHmWtDolneI15qeC0a19cwqYZ1m3YJ5qgwePeKI32n+ILIQDuFRwJTmBlgP4VfHzYsH5aNtKQVsdRvb2g1CdlNOJ9e8tVZ3B7r2BXE+3AaIlcioY//TmFDDPkhIUywnu7BlwW7zWG0mVAqaTSgGT5hQwNhMbNqgJh/jqhd5o/yGyeO65535ZOHtbhfP3d+Lr54I/o5+ff/75X0LbVgra6jDymU/VSbk3OobipJxOjE+eoAbkc5cCuZ5OA0QhcioY//SOvWmd6K/PwW3ThbQ6JSccI4bAbfFabyQ5BUzLpJU/OeFYMM8TvdH+Q+RRUVHxfPv27X/7xRdf/BralnJQTIdRM+hNdVKuOgFvQGFi0M9VpwGi1efCqWA817sxpyengGlKSlCsUsGYP8HVqX1nLlxVJ84ncgqYpnSKK4wd6YneaP8h0hCO369WVla+IjiUvlIMINqmUlFMhxGfMjHQlaooELGyqtMA0Ro5FYz3enMKmMJ0UsHEknBbvNIbbQungGmZXk7E2AEEQjh8vy/4meDVqqqq7eLrFfo5TJVAbAZZriwqzN5+qLaehg8O7Jo6DRCtkVPBeK93+tBRTgFTgPFJ76gJ7vnLcFu80httC9VX5hQwLZPyAHoRisEOIBDC2bslHL+OTX8nnL/Xw5YHkJjcvlPN5lauhDeesNAOPo8HGHyu0wDRGjkVjPd6JzZutFLAuA8+Dxvrly5RE9w9H8Nt8UpvtC2cAqYwqRKIF4ex2AEEQjh/PxJfvtLs11+1fm8Miukw0qfPK2dl+hR44wkLk1u2WuknVgd2TZ0GiNbIqWC815tTwBQmoi36rTfalsYUMPfhtuhGr9oiO4BACEdvHcX9Nfvd9wXXomwqB8V0GI2pOQbAG09YiFh10GmAaI2cCsZ7vRtXHW7C7dKNiNV4v/VG2sEpYFqnk5D9gw9c6432HyIF4fBtFNxgUaaAEbxkfX/JSgmzBW1nKSimw+DUHN6TCqQHHXekywDRFvnz5r3eXsUdhZGIeFy/9Ubakau1UsAM6A1/JjrSKck4b45rvdH+Q6RQUVExrhii7SwFxXYYVK9WLunfjcEbUBiIOHmoywBRDDkVjHd6P0pyCpjWGJZcp7q0b04B0zqz1++o5zN6uGu90f4Dw3AU22HEZ05XQb0nzsAbkOlE5R7TZYAohpwKxju9s9dve5Z7LKyMDeprTcjMzXWqS/tOfbzfSgGzCP5MdGQ+9YmakPXq4lpvtP8QabRr1+4fV1RU/LvKyso/FF//h020XaWg2A4jsXq1Ota/dRu8AZlOp/pAwOX1dBkgiiGngvFO7/Qh76oPhJXxyeangtGlfXMKmLYZ69dTTTjiGVd6o/2HyMLKA5inOsDi68/pq+DfC9aibSsFxXYYTmLPpUvgjcd0UmoEOSDPmRnodXUZIIohp4LxTu/kh5wCpi06dbn3BFOX20+90e27bs4stXp/lFPAFGLtO2PUhOPSNVd6o/2HyEI4epeF49efvqcE0NbXUYJDsJaVhmI7DI7r8I40M5YDspgpB3ldXQaIYsipYLzTu/7d+cq5OXgYbpOupJ0N2SZXvw+3xa3e6PbNKWDaZt2ihapN7jvgSm+0/xBZNM0DaDuAAr8gfp/GWVU6iu0wcrVpPtnlESk2Rjb+j/cHel1dBohiyKlgvNO7dpxKAUN1SNE26cr0idNqwjFzOtwWt3oj27dMAdOzM6eAaYPJTZvVhGPdOld6o/2HyEI4ffXf+ta3/qn1/d2Kiop//e1vf/tfiu9/iLatFBTbYciG3auLSiWR+gTegExm7cRxavn/4tVAr6vDAFEsVSqY1zgVjAd6x97kFDBtMXvH/FQwOrRvTgFTHNNHjqswoLmzXOmN9h8ii6qqqtnC2XvZ+n6w4GPBrOBytG2loJQOg46ty5WE63fhDchkUucoA4BFZxnkdXUYIEphzbBBnArGpd6f/+THVgqY7nB7dGY++6mYbLzcUN39dWNTwejQvmlSq0KFxsGfh87M3rynntOoYa70RvsPDAvC8fu9Dh06/MmXni0PpzVK6TCokLwM7j18DN6ATGU+/Vg+Q9omCXqg0WGAKIWcCsa93j+N13IKmCJZ89abasJRXQ+3pVy90e2bU8AURy/GAXYAGa5RSodBpwhl3MLGjfAGZCq9mPmVSx0GiFLIqWDc6/2jC2c5BUyRjE+ZqEIzzl2C21Ku3uj2nVi7VrXZzR/Bn4fudLsTxA5gwKisrDwneLYtou0sBaV0GKmDnE/MLdNHT7iO/SiXOgwQpZBTwbjX+8lO63TrBk4B0xbrl1mpYHabmQpGh/ZN/RqngCmOTiz4hfJiwdkBDBhVVVWdiiHazlJQSoeRvcYVBdySZsZuT3+VSx0GiFLIqWDc651bZp04F5M3tD26M7ltu5pwvL8Kbku5eqPbN+1syDjxm/fgz0N3Otkg9u4rW2+0/8AwHKV0GHm7pmhvrilaLusWu8//VC51GCBKIaeCca93ctJYTgFTJNMnz1ipYKbBbSlXb2T75hQwpdHJB7tmddl6o/0HhuEotcPwooRNlFk7YazrDPDlEj1AlEpOBeNe79p+PVQKmEQebo/uzN6NqQnH22/BbSlXb2T75lyxpTF9/JSacMyeUbbeaP+BYThK7TCQDkwYGOuPc6DRA0Q55FQwLpjMqwG5L6eAKYZPpYIRkw+0PaUS3b4zF69xCpgS6Db3JDuADNcotcOoX4ypYhEGUgJtefS/VxfI9dEDRDnkVDDlM3vtlhqQx3HMbrGsGdxPTTge1sFtKZXo9u2kgFnMKWCKodsJBzuAQFRUVDyPtsELlNphNNaxXQtvQKYxe+OuGpBHvw25PnqAKIecCqZ8pg9Zp/bf5VP7xTI+1UoFc/YiWtluaQAAIABJREFU3JZSiW7fdLCNU8CURjcTDnYAgaisrPyZ4C7BvxI//kM/ryWczbfFdf5ScKL4/htuX9cUpXYYdtxC3ZyZ8MZjGp3yP/NmQ66PHiDKIaeCcfHsNqq8nUnO21k06XMmdzh27YHbUirR7bsxBcwJ+LMwhfFpk6wJx4Wy9PbOy2CUhHbt2v0L4WgNqaqqumGVgVvUvn373/b6OsKR+127vJz4+nVxza1uXtccpXYY2dtW3MKIIfDGYxq9KADuhugBohxyKpjySSt/ckA+xClgiqWTCmaVealg0O2bU8CUzvoVy9UkbeeusvT2ztNglA3hfP074XTNEcwIx+surcR5tUUs3nOkeK/u9s/i/ZNuXtccpXYY+Yz5NTNRbEwBcxByffQAUQ45FUz5pNg/OSBf4xQwxTJ9UlVOodhTtC2lEtm+nRQwdOI8/Rj+LEwhOX5ywiEcwXL0du9hMFzjxRdf/C3hgM0WzApeptU3wR8Kh6yP2/cW77NA8OUmPyeef/75Xyr3dc1BHcbjx+rDVCztuIV8rL6k/xd1xq0T1NnL1yDXJ53L0RvJR/nGVDCPcp/B7TGJdPqXPm+fpPJwW0xh7l5jKhi0LaUS2b7zdY0pYNDPwSQ6OxzTJpWlt1v/glEmhNP3NeHgvUVbwMLZypED2L59+9+0/y5+968Ef+D2OrS1LK7zUpOfMy+88MIvlvu65mgoA+nZ0+SH9sd3b5fz3yOL+CBV+/Hnf/0jtClGoX7kYPnc/i6fQ5tiDH7+4x+rA0f9eqBNMQpf/PznDdVdX2mIdX+t4YvPP0ebYwx+Uv1A7W5Mm4A2xSj8/ZPHKi582ICy/r9b/4JRJoRz91PhZO3o0KHDn4sf/0FLrxF/X+H2OtbWbtcmP6fdvK456ENU6owxYcUtpHbths+gTOGjtEoBE5MpYH4IscHEFUCinQomc/os3BZTaKeAoUogpumNprPDUV0Ht6UUItt3ev8BtZW5ZBH8OZhEucPR/XUZVvUo92nJerv1LxhlglYAg7iOcOR+h1b36Pv27dtX0slj+l44ex2KeV1boA5DfhBLiVvYYcUtrFwBj6EwhRQYjUwBY8eMlKM3mpwKpnSmDh5W6SWWLzZObzRNTQWDbN+cAqZ8UiJoGRp052HJenvtbzA0hHD2pgjn7vuC0zp06FAhfvVl4eDFxO9/pY3XtYlyOozMGTtuYTK88ZhCJwXMXEwKGLvDMNEB5FQwpTOxQaWAebJzm3F6o2lqKhhk+6Z+jVPAlPnsZs9Qz+74qZL19sXhYEQH5XQYfDKzdNLMGJkCxu4wTHQAORVM6axboFLA/OjCWeP0RpNWmk1MBYNs35wCpnwm1q5Rq6cfbSlZb7T/wDAc5XQYVLbGPplJ5WzQDcgENqaAOQCzwVQHkLLkywnH4H5wW0xh7ViVAuZndbXG6Y2mqalgUO1bpoDp1YVTwJRJp4TektJK6LEDyHCNcjsMSpOg4haq4Q3IBNZaKWAyl67BbDDVAXx6wvEZ3B4TGOujUsB8/pOfGKc3mtm7jalg0LaUQlT7zsWtFDD9e8GfgYnMXLym4sPFGFGq3mj/IdKoqKjoVlVVdUTwJv1cWVn5+01TsZiAcjuM+KzpKm7hxGl4AzKB1DnKoHzRWaJsMNUBJNYMG6QmHGJwRtuiO/P1OTUgv/mGsXpDn5+YZNBkgyYdNPlA21MsUe27XAeGqZiLZywHumfJeqP9h8hCOHrjhMN3RXx9zc73Rwcv6Hdo20pBuR1GYs3qsuIWokjaFqFnRdskyOopJjuAdioY2p5D26I7M1duqgF5/Chj9UbTTgVD4QdoW4olqn07W5iLS9vCZDYy1rur2kJPPipJb7T/EFkIR6+e6gFb339m/frLTb43AuV2GKm9+6y4hcXwxqM7nRQwo4ZB7TDZAaSAfDnh2LYdbovutFPA1L8731i90TQxFQyqfSfWruUUMC5ZO2aEVbbxdkl6o/2HyIKqf4gv/5C+r6qq+pS+UuWNYhMw64JyO4zMhSvKqZk4Ht54dCelRkCngLE7DFMdgtTuPcqpWfYe3BbdmVivUsAkP9xorN5ompgKBtW+6+bMslLAnIQ/A1Npn9pPHTpSkt5o/yGyEI7eh8IJnGB9Lx1A8fPoioqKNVjLSkO5HUauJuXUfkQ3Ht2pQwoYu8Mw1SGglRiVCmYi3BbdWTd/rhqQDx81Vm80TUwFg2rfNSOHqtWrW/fhz8BUJjZuVGPEhg0l6Y32HyILqgQiHL4LtOIn+PeCtfRzhw4d/jnatlJQbochj/736NRQ3fn7Dfn0E3gD0pkUGyNndx/vh9phsgPIqWCKp50CJnv9trF6o2liKhhE++ZxwBumDx1Vu0Ri8laK3mj/Ier4MpVgq6io+K5w/v6T+PkraINKhZsOw5n5cfLPVumkgLmISwFjdximOgQyFYxVM5NzT7bOWJ9u8vP2KPnIWL3RNDEVDKJ9806QN8xev6NCqsYML0lvtP/AMBxuOozG2A8u/9MaqXOUJwprcSlg7A7DZIeAc0+2zcYUMD2M1xv6HA1MBYPQO3PhKseCe8B86pOSM0WwAwhERUXFb1RWVh4QfCT4E4s/pa9o20qBmw6DT38V0bDtFDA9O0NTwNgdhskOQXzmNCv35Bm4LbqyaQoY0/VG07RUMAi9ORuEdyw1Vyw7gEBUVVXdEM7efOEI/q74/t80Jdq2UuCmw7DzP1GZM3Tj0ZW6pICxOwyTHYL69zkVTFtMHTik2uTCBcbrjaZpqWAQeifWlFfHlvksayeOs0KFrhatN9p/iCyE8/dD8eXLaDvcwk2HwRng22ZjCphZcFtMdwhSu/daqWCWwm3RlYn169Vpwg8/NF5vNE1LBYPQu272DLUqf/wU/P5NJ62iys/b3n1F6432HyILSvcinMA/RNvhFm46jMYakKWVsIkSnRQwa9fCbTHdIcicu6ROZk6eALdFVzopYA4dNV5vNE1LBYPQu2bEEBWXe/sB/P5NZ3LLVjVWrFldtN5o/yGyaNeu3a9VVVXdF/xYOIKrmhJtWylw02HIFAC9uqgSNqlP4A1IR+qSAsbuMEx2CHLVCXUyc9CbcFt0ZdOKAqbrjaZpqWCC1lv2/290VClgMnwy3y3TJ06rz9us6UXrjfYfIgvh6G0Rzt8DigMUX6c2Jdq2UuC2w6gd/baVc+wuvAHpyFLjOvyk6Q6BHHAoFQwPOAUZ693NqSlqut5oOqlghg2C21IMg9Y7F1MTstigvvB7DwMpu0EpqYfYAQRCOHp/861vfeufou1wC7cdRt282VbVgWPwBqQjdUkBY3cYpjsENcMHW6lgHsJt0Y35uqyTAiYsekOfp2GpYILWO3P+slqxmvQO/N7DQMpvWsrnjR1AICorK6+0a9fuX6DtcAu3HUbigw+soPNN8AakG3VKAWN3GKY7BLQ9olLBnIbbohszV25YKWBGh0ZvNE1KBRO03qk91qGspUvg9x4W1gzprz5vD+JF6Y32HyIL4QAOqaqquiTYsaKi4n80Jdq2UuC2w0jtP+iknUA3Ht2oUwoYu8Mw3SFIrF6t0k5s3Qa3RTc2TQETFr3RNCkVTNB6c1v0nvFpk9Xn7fT5ovRG+w+RhXD84gVYi7atFLjtMDKXn151YDYyffSkGpDn4FPA2B2G6Q4BrzoUZtMUMGHRG02TUsEErTevxnvP+pUrlFO9Y2dReqP9B4bhcNthNI87YjZSpxQwdodhukPgxB1N5rij5nRSwFjxuGHQG02TUsEErTfH43rP5M7d6vMmJh7F6I32HyKPb3/72y+2b9/+P7cTQNtSDrzoMJyTh4lH8AakE+uX6JMCxu4wTHcI+ORhYVIheXUi/05o9EbTpFQwQertnMjv8rI8vIC+97CQQg3k523qxKL0RvsPkYVw/P5lVVXVKcG/E8xaX09/85vffAFtWynwosNomnsM3YB0ok4pYOwOw3SHgHOPFWbTFDBh0RtNk1LBBKl3rrpePZe3OCcn6rmyAwhEZWXlNsHFzz///C/Rz/RVOICLBHegbSsFXnQY9tZT6tAReAPSiY0pYFJwW+wOIwwOgbP1xNUHHDqhGP0aQzHCojf0uRqUCiZIvZ2qPFPaXqliFs9Scp2yAwiEcPQ+qaio+EdNf9euXbt/LH7/GGVTOfCiw0is36Bi3TZuhDcgXZhPP5GNWJcUMHaHEQaHIM71R5+hcxjrnTGh0xtNU1LBBKl3avcersvtExvL67UeW8kOIBCVlZU17du3r2z6O/o5aqeAZWdw8LA67bpgHrzx6MLsrftqKX/kULgtTTuMMDgEVCtTnpTbshVuiy5sngImTHqjaUoqmCD1pkMxsg1u2w6/77Cxbs7Moia47AACIRzAYeTsia/9Kioq/oy+klMovn8bbVsp8KLDyF69pVYfxo6ENx5dqFsKGLvDCINDkNq7j1PBNGNLCdnDojeapqSCCVJvOhQjnZSTZ+D3HTZS1gjpXH+0pU290f5DpCEcvs6ChwTvWl87i19/GW1XKfCiw8gn8ir+qE93eOPRhdR4VQqYNXBbmnYYYXAIGktQjYfbogvr5s15piRjWPRG05RUMEHqTfVq5Tbl3Rj8vsPG1L4D6vO2eFGbeqP9B4bh8KrDiPXtrk4g1ufgDUgH6pYCxu4wwuAQ5GJJNeEY2Aduiy5sngImTHqjaUoqmKD0psMwdCiGDsfQIRn0fYeNmcvX1Y7ahLFt6o32HyKLioqKl9q1a/cd+r59+/ZVlZWVJ6qqqo7S92jbSoFXHUbtuFEqTubKTXgD0oG1E8er53FBjxQwdocRBodAnpTrYaeCeQK3RwfGendVE7DUJ6HTG01TUsEEpTcdhpHPY3A/+D2HkTnnRH/PNvVG+w+RhXD4Yi+++OLXrO93C84XTuFk4QQeRttWCrzqMOrena9WvA4cgjcgHahbChi7wwiLQ0CHa+SK1y1OBVNowAiT3kiakgomKL0zZy9YyYonwe85rIz1eTqnZyG90f5DZCEcvR/RV0r9Ipy/H9JX8eNXxe8/BZtWErzqMCgFjIx5W78e3njQdFLA9OikTQoYu8MIi0NQZ6eCOXYSbguaLaWACZveaJqQCiYovUspV8Ysj3Sgsq3iCuwAAiGcvkSHDh0qhMP3F+L74/Q7ygtIziDYtJLgVYeRPnRUnXqdPxfeeNDUMQWM3WGExSFIrFlT1Em5KDC1/6Bqe4veDa3eaJqQCiYovetXrlRtb/sO+D2HlZRSTe6oHSxcXIEdQCCEozdE8MdE4fj9f/S79u3b/7/i5/No20qBVx0GzVTkKsSY4fDGgyatSqkUMDPhtjTvMMLiEDipYJYshtuCpp0CJrlp01O/D5PeaJqQCiYovePTp6jV91Nn4fccVjbuqG1oVW+0/xBp0IEPgfZNfxb8TaRNpcKrDoNiFWQcUu+u8MaDpo4pYOwOIywOAR2ukROOiZwKpqUUMGHTG83GVDAr4bYUYlB61wwdqLbD79XA7zmspLbc1o4aO4AM1/Cyw6A6pLJjqMvCGxCStColVwv27oPb0rzDCItDQIdr5IRjQG+4LWjWjrZTwNwNrd5ompAKJgi9ZQqYrq8KcgoYP0ltWU5wRxfeUWMHkOEaXnYYFIQu42QuX4c3ICR1TAFjdxhhcQhUKphOKhVMOtqpYGK9ujyTAiZseqNpQiqYIPTOPYir5zBkAPx+w0xqy/Scq0XbLnSQkB1Ahmt42WFQELpc+dp3EN6AkKQExXIltEafFDB2hxEmh6AxFcx9uC0otpYzLGx6I2lCKpgg9M6cPq9WQqdNht9v2NmYSixdUG+0/8AwHF52GBSELmPf1q2DNx4UdU0BY3cYYXIIqM6yjH07Gt1UME7VgGYpYMKoN5q6p4IJQu/kjl0qFnLFcvj9hp1t7SSxA8hwDS87jPSR4ypwde5seONBkRIT65gCxu4wwuQQOEXTN38EtwVFWm1XKWAWhl5vNHVPBROE3uT4yTYnHEH0/Yad9UuXtBpLzg4gwzW87DCyN6zA1VHD4I0HRV1TwNgdRpgcAqqzXEzR9DCzUAqYMOqNpu6pYILQm7Z+5ar76fPw+w07k1u3qR211asL6o32HxiGw8sOwwlc7dlZu+3PwBqtnQJmjV4pYOwOI0wOQebi1aKKpoeZdfNmqwH5yPHQ642m7qlggtCbDn/IbfD7tfD7DTvTJ86oeMuZ0wvqjfYfGIbD6w4j1r9Xq4GrYaeuKWDsDiNMDgF9xqKeCqZ29NvqIMyNu8/8LWx6o6l7Khi/9ZYHYbq+ItPA6HoQJkx0Tp6//VZBvdH+A8NweN1h0GqMjJO5qFcKlKDYGLh7BW5LSx1GmBwCmQqmZ2eVAiX9GG4PgoVSwIRRbzR1TwXjt96U+Fne/9CB8HuNAhtPnrfscLMDyHANrzsMiseSK2Af74c3IASdFdC4fiugYXQIKN5UroDdvAe3JWjm4hm1Atr/2RQwYdUbSd1TwfitN5V+kyug06fA7zUqdLbcH8Rb1BvtPzAMh9cdBp3I1LEMWhDMJ+xyeN3gtrTEMDoEdXNnFYyBCzszl661GgMZRr3R1DkVjN96J7fvVDGQK/WMgQwjnbrLLRy6YQeQ4RpedxiUk03XU7B+M3v1lhqQx42C29ISw+gQUM7JqKaCaS0FTFj1RjM+dZIK8ThzAW5L0Hrbp6CTO3fD7zUqJGdbPnPhfLekN9p/YBgOrzsMqsqgax48v5nabw/I78JtaYlhdAhS+w6oZ764ZScozHSc302bI6M3mvUrVxQckNH0W2/H+T2rn/MbVlLKIbnqKpzvlvRG+w8Mw+F1h9FYCaNj5FLB6J6YOIwOQeZi69ugYSYlXG9t+zuMeqOZ2m0NyMuWwm0JWm9n+7uFeDSmP8ycu6TiLqdMbFFvtP/AMBx+dBhOLdxYEt6AgmR89gw1IB8/BbelJYbRIaDDNq0dhAgznVrIBQ7AhFFvNDPnL6sBedJ4uC1B6q37AZiwMledUDtqg95sUW+0/8AwHH50GNQ5yq0C0VmiG1CQpHxNckC+Uw23pSWG0SGQqWBaSYUSVtIgXN39dbnans88iYzeaOo84fBTb91T4ISVsn97o2OL7ZwdQIZr+NFhODUM93wMb0CBNVQakLu+KhOl0mwZbU9LDKtD4CRDvv5sMuSwkrbh5IA8uF/k9EaTTvnLCUfiEdyWoPROnzyjdRLsMNNZ6b/14Bm90f4Dw3D40WEkt2xttYZhGNk4Q9Y3SWpYHYK6eXPU1vuho3BbgmL61Lk2c7KFVW806ZS/3OG4chNuS1B6J7dtt8rgrYLfZ9RYN8dKdXX05DN6o/0HhuHwo8OgGDg5OM1quYZhGJk+cbrVuo06MKwOQWLjRjXhWL8ebktQtAvF179feEAOq95oUtoducOx7yDclqD0rl/2nrrn3Xvg9xk1Fkp1xQ4gwzX86DCytx+q1bDhg+GNJygmP9qinJA1+ibADqtDQKdgZSqYubPgtgTF+iWL2qw5HVa90dS1rfupd3zyBLXqee4S/D6jxkL5PtkBZLiGHx1GPvOpSgXT/fXIpIJpXBU4ALelEMPqEFBsTNQmHLXvjFED8qVrkdMbTV1X+/3UOzagdyQzO+jAzOUbKtWVaPPN9Ub7DwzD4VeHQcfWZYdRXQ9vQEGwdrwdF3QDbkshhtUhyGc/jVyKiljf7uogQn0ucnqjqWu8r19655OqxCWdto/KhF4n5uuy6uT5mz2e0RvtPzAMh29bBlMmRiprfKyPfTIwD7elEMPsENQMtYqm36uB2+I3cwUGhCjpjaQ88d9NvxP/funtlLgcOxJ+j1FlrE/3Z8YXdgAZruFb0PCK5dqWTPKaTm6wfvrlBmvKMDsE8ZnT1Em5E6fhtvjNzMWrRVU/CbPeaDbm/HwIt8VvvZ1yi5qWuIwC7ZPn5Iw31RvtPzAMh18DRGr3XnVK8T39SiZ5zcwFa0CeOA5uS2sMs0NAAfk6l+HzkpRfU7atpUsiqzeadXbVn2Mn4bb4rXdizWrVtj7aAr/HqLJu4QIVY37w8FN6o/0HhuHwa4BwnKII1GgtdkBGM8wOgXNSTnSUaFv8Zv2qlWpA3rY9snqj6aTm2LQZbovfelPyZ7W6fgZ+j1Fl4sNNz6S6YgeQ4Rp+DRBOnFLfN+CNx29SctRiBmQ0w+wQRClOKT5tkhqQT5+PrN5opg4c0m7C4ZfeNUP6q/ja+7Xwe4wqnVRX8+Y8pTfaf2AYDj8HCApSlx2HcAbRDchPUjWGYgZkNMPsEFAd4KicVKx5yzph/7Ausnqjmb12W004xoyA2+Kn3jKlV5eXVUqviJyw15HZm/fU523020/pjfYfGIbDzwGCYuLkSeALV+ENyE9SPdZiBmQ0w+4QRCFXWT79ROXY7NGxTUc37HpDddBwwuGH3rbjQfVo0fcXZebTj1W779nZ+byxA8hwDT8HCDoAEvbyQfnMEzVDfqOj9jPksDsETrWCsxfhtvjF7I27aiVg1LDI641mbGAfNeGoScFt8Uvv9OFjz2w9MjF0Jri1KUdvtP/AMBx+DhDJHTvV4YgVy+GNxy9mb903ZoYcdofAST20I7yph1KHjqgBef7cyOuNpm7l0fzQmw4dyMMHGzfC7y/qjE8ab+2oXXH0RvsPDMPh5wBBHaMsmSQ6SnTj8YuNwbmz4ba0xbA7BKlde9SEY1l4Uw8lPvig6AE57HqjWb98mZpw7NwFt8Uvvam+toxvFv0c+v6iTsoyIXfU9nzs6I32HxiGw88BgrZG5EngAb3hjccv0kCsjudvgNvSFsPuEGTOX7byMY6H2+IXSxmQw643muT4yQmHcATRtvilN9XXlgmIbz+A31/Umdy6TY01q9939Eb7DwzD4ecAQcGqsd5drRI2j+ANyA/SVpwckA8dhdvSFsPuEDgVWfrrXZHFDUsZkMOuN5q67XB4rbdT8q7LK7LeNvr+os70yTPq8zZzmqM32n9gGA6/B4ja8aqETebKDXgD8uX+Rr+tBuQbd+G2tMUoOAQm1GQul2pAfq3oATkKeiOp2w6H13pn78ZUfPPQgfB7YzbRY9ggR2+0/8AwHH4PEPWLF6m4hY/3wxuQ16QVzuoeneTxfDqmj7anLUbBIagdP1pNOC6Hb8KRu19jDcgDWG8NKNt/ry5qwpH6BG6P13qnj59SK06zpsPvjSk+b9nPGqq7viJXZWkyyA4gwzX8HiDsuIX691fBG5DXzFUn1ArAoL5wW4phFByCME84qBSXHJBnTGW9NSElgpY7ANduw23xWm8qcydjztauhd8bU5Emf3ZVFnYAGa7h9wCRPnVODVrTJsMbj9fMnL2g7m3qRLgtxTAKDkFyy9anAqXDxORHW9S9rVnNemtCKgUnJxwHDsFt8Vrvunfna3NvTEWn6pQYV9kBZLiG3wMEVceQ21ZvvQlvPF7TtDyHUXAI0ifPKqdcdJRoW7xm3aKFakDed4D11oTOKtm6dXBbvNa7dsxwbVY3mYr1q1aq1EPbd7ADyHAPvwcI0+LkSmqMy95TA/IuMyqdRMEhyD2IqwnH4H5wW7xmqQeqoqA3muljJ1Ue0Nkz4LZ4qXeY+22TSVW1VK7T99gBZLhHEANE7ehwziTjk95RA/L5y3BbimEUHAJ5Urb762rgyjyB2+MlY73tE87FpVSKgt5oZu9UqwnH22/BbfFS71x1vVHxzVFh09RD7AAyXCOIASKssSTNazPqzqg4BFSWT044bt6D2+IVc7V2jsNerLdGbH4yE2mLl3pnTp+3YrcnwZ8xs5G5WOPBQ3YAGa4RxAARxtNk+eQj1RB7dZHbJWh7imFUHAIqXG9Kcu5iaVc5oXqgrLderBk2UE047sagdnipd3LbdrXVuGol/PkyG6m25jvKHY5H2SfsADLcIYgBwsknNTM8+aSyV2+psmNjR8JtKZZRcQgay/Oth9viFRvrHL/HemtG6tfkhOPEaagdXupdv2TxU3VnmfrQ3uHI3brPDmDYUVFR8XZlZeVfCk4U33+jtddWVVX9G/Hlq88///wvdejQoaKY9w9igMjdsxPYhiejPG1ny+DvhQvgthTLqDgEVCdXajN3FtwWr0gnzeXpvx07WW/NmFi7Rmnz0RaoHV7qXfvOGBXffPEa/Pkyn6ZTD/zYCXYAwwzh8P2ucOqW0/fi69eFE7i1tdeLv18Tr3ssuP2FF154rphrBDFAOIH5VMIqE46akpT2QXb6mzbDbSmWUXEIsrceqAnH8MFwW7xifMpENSCfvch6a8bUvoNqwrFoIdQOL/WO9e2uDhzV5+DPl/k0nbFn82Z2AMMM4ciNFE5gd/tn4eAl23h9x1KvEdQAUTNiiIqTuXUf3oC8YN2cmdYs7CTclmIZFYeA6uTSZIPq5qID871ibGAfte0TS7LemjFz5aYKBxk3CmqHV3rn4hkV39yvB/zZMp9lar+acNQvepcdwDBDOHwLBF9u8nOCtncLvV44gNM6dOjwJ+LriHbt2n2nmGtQh/H4seo8/GTdvNnKYTp8zPdrBUFaXZID8t2HcFuKJekclN5oNpZMqoHb4paP0p/Ie6nu2VkMAD9kvTXjI/tAWO9uUDu80jt78YqK2Z44Dv5smS3oc+WG0ued0ewAhhnCkVtUUVHxUpOfMy+88MIvtvJfvkz/PPfcc78snMVzxVyjISA82alqAj/ZsSWoS/qGLz7/vCHW/TWZ/uGLv/97tDmMFpBZoOJk/ubaFbQprvGzulp1qGXCaLQpjAKID1IpoX7+ox+iTXGNHxw7LO/l0dpVaFMYLeDnf/M3asW5Xw92AE2HcOp+j5w1wbPNuJVW8oQD2LXJa9OF3qdDhw5/Lv4+2/rxK+L//7iY69MHKogVgvTRxsB89AzKLWlVyT7UgralFEZpRagxMP8juC1umT6oDhzVvzuf9daUlJ5HhrhcvAKzwSu9E9aBo9SOnfDnymyZdozm5e916jvbAAAgAElEQVR+91dduiAMXSEcut+hVUD6vn379sKnq9xl/004hh2avlY4gH8gXvPb9P2LL7746+K1B4u5BnUY9IHyO24hezs8gfnpk2estDbT4LaUQtI5KL3RdALzDTqlXYjlHjiKkt5o1i9bqpym3biykF7pTVUmSj1wxAyWdlnI+6//1X/00udgaAbh6E0RTuD3rfg+O7XLl4WDFxN/+5Vmr+1OK4bibxN0OgVMlIH5mmTMd8vklq1qS27NargtpTBKDoGJeRoLMT57hoqfPX6K9daUlJ5HrtKuXAGzwSu9nQpHNWZUOIoiaWJLGj3s+N1XPHc6GNFBkAOELhnz3bJ+8SI12/94P9yWUhglhyCf+sS4Si2FSHVmZbu5U816a8rM2QtqV2AqrnSaF3qbWOEoikxu2iR1etDxpfFoH4JhMIIcIJyVDINSp7REJ0nq5RtwW0ph1ByCMKxkqFqzr0rS96y3nsxVqxqtNYPehNnghd5OSpsQrJyHmXay+4cdX9qA9iEYBiPIAaIxlmkTvAG5oalJUqPmEDixTOcuwW0pl7RaLh2LYYNYb42parR2kjVa8+nHEBu80Du174AWSa2ZrTN7855KDdXppctoH4JhMIIcIFIHj6jOZcE8eAMql7m6rLFJUqPmEDSWT9sFt6VcOnW0Z89gvTVn7ejhaqv++l3I9b3QO7F6tRZl7ZitM59+IicbDzu99AjtQzAMRpADBHWMcnth1DB4AyqXVBtT3sOEsXBbSmXUHILUrj0qMH/Ze3BbyiWd/JUHjtatY701J01sZWzwoSOQ63uhd3zGVBWmc/IM/HkyW2dq27aGBx2/+xbah2AYjCAHCHvWUv1GR2NPAqf27lNOxZLFcFtKZdQcgsz5y2r1bNJ4uC3l0j7tlzpwiPXWnIkPP1TO+gcfQK7vhd41Q/qruNkHcfjzZLatN9p/YBiOoAeImsH9jO5gnG3FbdvhtpTTYUTJIcjF02q7vn9PuC3lsnbMCLWteO0266057cB8SnaPuL5bvfMZa4Le/XVjJ+hRIjuADNcIeoCIT59ibTGchTegckhbv/JgwYUrcFvK6TCi5hBQfVZ5YCeRh9tSKuXBgl5dlP2pT1hvzekkux8xBHJ9t3rbBwtqRg6FP0tmcXqj/QeG4Qh6gDA5yFgOyD07q5N+iUdwe8rpMKLmENgZ801L2UPMxZJqBXNgH9bbAMpk910o2f1rkBU0t3qnDx1VK5jz58KfJbM4vdH+A8NwBD1AmJxmIHfPqgE8pD/clnI7jKg5BHWLFxqZtJtIpbhkDOOUiay3IXSSdt9+GPi13eqdWL9exTBu3Ah/jszi9Eb7DwzDEfQAYXKJrvThY8p5nYOJ8fGiw4iaQ+CU7Vv9PtyWkm3fsUsdOFqxnPU2hHXzZqsQl0NHA7+2W72pX5O2HzkOf47M4vRG+w8MwxH0AGGX6Ko2sNRQYs0aK5H1Zrgt5XYYUXMIKNZUrqJNnwK3pVTWL12iVi9372W9DaGTtmftmsCv7VbvmuGDrdXLB/DnyCxOb7T/wDAciAGCYprkSeBYEt6ISmF86kQ1Qz59Hm5LuR1G1BwCOm0ut+0H94PbUipplVzGL14pL34xinqjmT5lTTimTQ782m70ppjF6m5UcvAVGcuIfo7M4vRG+w8Mw4EYIGxHigqooxtRKYy92UM5rvE03JZyO4yoOQRyYOvREVqiq2y733BndxT1RtM5uDOgd+DXdqN3Y8nBgfBnyCxeb7T/wDAciAGifuUKtZW6fQe8ERXLXCwB69i97DCi6BC4XUlD0BmQh5Y/IEdVbyQprCXWx6oVXpcN9Npu9HZKDs6aDn+GzOL1RvsPDMOBGCBSe/aq4PalS+CNqFimT5wxNpasaYcRRYegMZZuD9yWYukcOHKRVDiqeqNJlWfkhOPcpUCv60bv5KZNVuziWvjzYxavN9p/YBgOxABhYj3dxIYN0DJPXnUYUXQIyPEzbcJBA7E6cLSJ9TaM9StXQqoFudGbJhoyvllMPNDPj1m83mj/gWE4EANEvj6ntlP7dIc3omIZnzlddZDHTsJtcdNhRNEhoK1f01IPeVExJ6p6o0k5J1Wu03cDva4bvWuGDFAngO/G4M+PWbzeaP+BYThQA0Ssfy/rJHAC3pCKstc+ufywDm6Lmw4jig4BHaKQNU7f6GhMjVOKNXXbPqKqN5rZ63fUhGPUsECvW67e+eQj1T56dDKmfTDZAWR4ANQA4axwnDgDb0htkYK51YplN+NyFzbvMKLqENDpRrnCcacabktbzNmft77dXX3eoqw3kvlMk5Jw2c8Cu265ejshOeNHw58dszS90f4Dw3CgBgiKpTOl7JBTkmvSO3Bb3HYYUXUIkBUaSqVXn7co641mY0m44JIql6t3csdOFSO7fBn8uTFL0xvtPzAMB2qASB89qQa5mfqnHUh+tMXYcmLNO4yoOgTJzR8pDdcEX6GhZFu3blMD8qqVrLehrJs/V508P3gksGuWqzfVZZe27t0Hf27M0vRG+w8Mw4EaICiWTm5zDeoLb0htsW7enMA7c786jKg6BFS9RU44pk6C29IW696drz5v+w+y3oayccKxOrBrlqs3xSrK1cprt+HPjVma3mj/gWE4UAOETJjauxskYWqppGS8Kn7sIdwWtx1GVB2CXG1KTTj69YTb0hZrRgxRn7eb91hvQ5k+dc4qCRfchKMcvansW3VXqwRchkvAmUR2ABmugRwgKMZJlYS7CG9MhZhPfWKdkDPnBGlrHUaUHQJy/uTJWuEMom0pxMYB+VXXNVmjrjeSuRprwtG/V2DXLEfv7I27quLMyKHwZ8YsXW+0/8AwHMgBov79VSph6kdb4I2pEBtPyI2C2+JFhxFlh4C2f+VBkNPn4bYUopcDctT1RjPW9w014Qhoh6McvZ2chQsXwJ8Xs3S90f4Dw3AgBwiKqZOdz7w58MZUiGE6IRd1h4AOgMgJx+aP4LYUYmrfAc8G5KjrjaazwxFQSbhy9K5fsRxStYTpjd5o/4FhOJADBMXUuS147zfDdEIu6g4BpYBRE47ZcFsK0SkjtnUb62046RS3V1r6pXftO2OUk3rhCvx5MUvXG+0/MAwHcoCgmDqKraMYO4q1QzeolkhbcTIg//pduC1edBhRdggoCbSccAzTd8IRnzTes1WjqOuNZmrfwUC3V0vVmw7iVffsrA7iJR7BnxezdL3R/gPDcKAHCIqtkwPexWvwBtWcMqM/BeR3cx+QrwOj7hDICccb1oQj/RhuzzP20cn4Pt6djI+63mjSpDHIAxal6p27X6PsG9wP/qyY5emN9h8YhgM9QNQve09tk+zYCW9QzUl5sRA1Pf3sMNB6o1k7dqSacFy5AbelOXPVCXVydEBv1jsElCe6u72mUqykn/h+vVL1Th85rlYoZ8+APytmeXqj/QeG4UAPEBRbJzuhRe/CG1RB2xYvhNviVYeB1hvN+qVLVEzn7j1wW5ozffKMyh03fQrrHRI6E45L/u9wlKp3Yu1alaz6ww/hz4lZnt5o/4FhONADRPb6HW3zUDWuTu6C2+JVh4HWG01y/OSpbuEIom1pTqc+tvjKeoeDQZ6yLVXv+LTJKi2SmHignxOzPL3R/gPDcKAHCJ0z0deOs+ITL1+H2+JVh4HWG03a+pXb+mNHwm1pzvjUidaAfJb1DglTBw8HluqqVL1j/a3E6LEk/Dkxy9Mb7T8wDIcOA4SOtSifOjCg6QnlcjoMHfSG6pp+LCcbFJul08EeVRqxq6eJg1lvPHP3gjtoUYreudq0ijd9swf8GTHL1xvtPzAMhw4DBMXYybisPR/DG5XN7O2H2qcMKafD0EFvNGtHv20dBLkJt8Wmk6JmSH/WO0RsWvPc74ogpejt1CqeOhH+jJjl6432HxiGQ4cBgmLsZFzWe0vhjcqms3Uzfy7cFi87DB30RtOJ7dy+A26LTSdnnIefN9ZbDzpb+6e82dr3Qu/Ehg0q3nTtWvjzYZavN9p/YBgOHQYIirHTLS6rfpX+dYrL6TB00BvN1IFD2lUEqV+21HJKvUuHxHrrQedwz/oNvl6nFL0b4035AIipZAeQ4Ro6DBBPxWVpchDEy4oMupAdAkUnAe6gN+G22HTiYK/eYr1DRie9z7RJvl6nWL0pvjnWq4tnCceZGLIDyHANXQaI2jHDA8uX1Rabxu3k63Nwe7zsMHTRG65v3+4qLqs2hbcn/cSXgymstx7Mxa0DF326y8+eX9cpVu/srQfa12BnFqc32n9gGA5dBggnX5YGW665B3HVYQ/qC7fF6w5DF73RpGTLcgvs2Em4LVQG0Y8QCNZbH9Jqs5xw3K/17RrF6k2H7YKsUcz0T2+0/8AwHLoMEOnDx9Q2yczpeFuOnlS2zMLb4nWHoYveaCY+3KTistashtuS3LJVHYJauYL1Dinr5s5WmQ4OHfHtGsXqTVWXVNaFvfDnwnSnN9p/YBgOXQYISkYqV936vuHrNkkxTKxbp5yDjRvhz8XrDkMXvdGk2E656jZhLNyWujmzfHEOWG99mNy6zRcnvxy9KbWVjDe9dR/+XJju9Eb7DwzDodMAYW+TZO/GoHY424MhOyHHDkEjKbk3JfmmZN/57GdQW2ID+6jtwQdx1jukzFy8qiYc40f5do1i9KZDH2RHda8u8jAI+rkw3emN9h8YhkOnAYJyoMmVkI/3Q+2I9e8VyhJJ7BA8zZoRQ+AVaHI1Kacig9cr36y3PpSZDrq80lDd/XXfJhzF6E1lBjkBdDjIDiDDNXQaIJI7rYTQSxbBbAhziSR2CJ5m/ZLF6uCR+NyhbKBDKHJAnjGV9Q45a0YOVROO63d8ef9i9HbCW3zOScj0n+wAMlxDpwEie+OuSk/w9lswG9LHTwWSswvVYeikN5q00ixPQy6YB7MhsWaNGpA//JD1DjntCUdq1x5f3r8YvZ38pmcuwJ8H073eaP+BYTh0GiAoJqW6Z2cZm4XKv0dB2nJVaPNH8OfhR4ehk95oZu889Lz+bqmsnWgNyGe9H5BZb72Y2rvP1/Qrbekt+9ceHVX/mngEfx5M93qj/QeG4dBtgIhPwZYosuPCMlduwp+FHx2GbnojqRJ+d1XxnvFM8NeXA3In3wZk1lsvZm9bCZgH9/Pl/dvSO3vd2mEZPhj+LJje6I32HxiGQ7cBAlmkPEcn5OhkaM/OoTwhxw7Bs4xPnaQmHCeCn3Bkb97zNeSB9daLcsLRr4eacDysC1xvJ8Z66RL4s2B6ozfaf2AYDt0GCNoKQ+VnSx85ruL/pk+BPwe/Ogzd9EaTguHlhGPdusCvndy23Tr0tJj1jgj9zHTQlt7OtfcdgD8Hpjd6o/0HhuHQbYCQ+dm6vGylS/CuLmoxrF/2nor/27IV/hz86jB00xvNzOnzsAmHk29STDxY72jQiQMUzljQetPWsw55Vpne6Y32HxiGQ8cBonbUMEgcHm3FofPC+d1h6Kg3knLC0fVVSfo+sOuKyY0T/1eXZb0jQqfOeL+egeZ9zNVa+Sb7dIdXWmJ6pzfaf2AYDh0HiPrly9RK3LbtgV3Tyf/Xu2so4//sDkNHvdG0T+IGefAoc8GqDDF6OOsdMTorcbcfBKZ3+tBR3/JNMjFkB5DhGjoOEFQTVW6TzJ4R2DWdDnLmNPj9+9lh6Kg3mpTyR8biiYlHUNdMfPCBddhpDesdMVKieznB3bEzML0p9YxKer4bfv9M7/RG+w8Mw6HjAOGUx6J6lQHVaaWTcUGvOiI6DB31RpMqM8jTuEMHBnbN2nGjVJjDuUusd8RoT3DjM6cHovdTp4/v18Lvn+md3mj/gWE4dB0gnDjAC1cCuV7N0AFqW+bmPfi9+9lh6Ko3krTlH+v7hm/pOZ65XiLfeNAp84T1jhidcBOa4HoYblJI78YJzgD4vTO9IzuADNfQdYBwtshWr/b9WrlYIhIB0uwQFKaTImPPXt+v5ZQbnDKR9Y4oKRmznHBeveW73slNm1SIw4rl8Ptmekd2ABmuoesAkbl8I7Cs9akDh1TM4ZyZ8Pv2u8PQVW80U/sOBvYZcNINfbSF9Y4o/Sg5WUjv2nfGqENOp87B75vpHdkBZLiGrgOE3Jbr0z2Qbbm6xQutAOld8Pv2u8PQVW80n4o79fkUOMUaytWf63dZ74gyfeK0WgWePMFXvVW4wSsq3CDtX7gBM3iyA8hwDZ0HiLoF89S23K49vl6nMS3DQ/g9+91h6Kw3mk4d6Ms3fLsGTWako9m3u++OJuutL6n2s+OYZbxJeN+S3umjJ5SjOXUS/J6Z3pIdQIZr6DxAOKflfCzNlrtfYyVm7RHq+D+7w9BZbzQTq99XcafrN/h2DSoBJrea581mvSPO2rEj1YTj/GXf9K5fbKWc2b4Dfr9Mb8kOIMM1dB4g8vU5309LJjdt9rUeq05kh6B1OnWox4/y7Rp18+aoVe29+1jviJPqT3tZh7q53jL9y4DeXP4tpGQHkOEaug8Qfgcw14wcqmbhZy/C7zWIDkN3vZGkSQZNNmjSQbFTnr8/DcgBppthvfVm5uJVJ/+kF7sP/397Zx4kRXXH8QIrJGXUJOVuSJYgu7OzGytHWf6hKao0MXf5RypR4wYhWRQMioiFF0TjEQMaiIqKghKCSDwAA2rAI14kEoUQDkVAjgWWnd3ZA4lHKibRxJr8ft2v12acZWeme/ZNT38+VV+mj/d6X/Pr49e/d2Xbu2vrTvf4l11s/VxR+MIBhMCU+wuiN0JXglka9Kt4oNpjlYNwCPqXtpVyPjhWvxD6sTs3vDyg47Fh7/KW09FtykWmQ9D20O2tvcydZ+dv7rF+rih84QBCYMr9BaEDMzsvzcsnh37s1NKl7gPynrutn+dAPTDK3d621b7iEbeN3tw7Qz+2N9tM6sEHsTdy1NvuVH7DtnfrDDPH9QsvWj9PFL5wACEw5f6COKQdy/Zwe+n29voMqRF2uQuHoH85vXTPHZVpueDcTE/H66EdV3t67pk4zq3+3bEXeyNHOhSQUwsx5aLAtRB+ezu9jMeNybSMHxPqdYzKRziAEJgovCC0g4bTk235itCOqc5kb+/fGFT/eg+MKNjbtlpn3OB21PjjM6EdM716jdvB5PrSdTDB3tGTfuDunTrFTHu5OTR7d6x63B1BYeaN1s8RlUY4gBCYKLwg0mvWutXAV10R2lAtqYceMu1j5ls/v4F8YETB3rblzQyzb/ovQjtm6y2zzGDjq7A3OkSpJUvcZ9H8YG31/Pbed80005Z1jfXzQ6URDiAEJgovCH9jaW1IH8Yx9067zHx1b7J+fgP5wIiCvW2rJ33QqQLWquDuXa3Bj7e/y62OE+ky9kZ+9XZG07nIu94MbO/uLds/qN0IcDxU3sIBhMBE5QXhddjYf8dtgY/VtXWX+4C85ILYVP96D4yo2Nu22u6eG1qHDZ3JxqmOu3kW9kY5te/an5nhrtYGtrf2+nWu3cWLrZ8XKp1wACEwUXlBdO/ryLSMG+1EUbpb04GOlXrgAbfK5bcLrJ/XQD8womJv2+rc+Ir7kXDppMAfCTqwdKmGlsHelaHe3udzbg9k7/fffdeZz3ogOxshO8IBhMBE6QWh02c57age/n3Rx3AaXV9pGl3/LZzq5KgIhyB/HXKdrNtQ9HF6pxqcOC60OV+xd+Wpe0/K7X0+YazTBKFYe7/9opn7d0Z47VdReQoHEAITpReEttcLGpXxJkfX0fHjVP3rPTCiZG/b0g+NoFEZnVfY1liT2Dta0k5HTu/zZ54v2t7tN17vHuPZ4o6BoiMcQAhMlF4QTlTGdN5Ir3mp8Pzi8Hn5O5562vr52HhgRMnetuVEZby5qFMHCs7vXG+XT7YWbcbe0ZIOO+R8nE6dUlTnje7tpm3zReNLNnc6Kh/hAEJgovaCaH9spVvFMeumgvN6w3s4c2/GLPrnPTCiZm/bap05o+jhWzQKE+Zcr9i7snXIB+qqJwrOn7p3odv5Q35tnwsqvXAAITBRe0E4I9xPaC54iA79ovaiMenn/mT9PGw9MKJmb9vSSLPbY/zCgtpmOS9z04aw2Co97B0/eWOeOkO4FDCDR09bd2bPxPFu54/tu6yfByq9cAAhMFF8QXhzqrbNm5t3no7Hn3SjMVdfGcvon/fAiKK9bUojd/tuuLbgzke90eapl1q73rB39KTXmzeHbyFDELWZ6F969izsHRPhAEJgoviC0MiftsvSKGA+A0NrexhvPuE4T4yOQ1Cc9BpzojIXnudEWvpLr5Eb7WRkO9qMvaOprpe3uT2Cf9qc6d7T3n96HUhah8g6b3Tm3c409o6JcAAhMFF9QbQve/iD6eH6aTDd/ugf3Km9rrvaSluschEOQfFqvXmm2yP49tn9XkNehNq53ixGm7F3dKU9z51ajrsPX8vhRAxNO9XUwgXYO0bCAYwJjY2NExKJxCn9pUsmk9MaGhrOFE2X5c/lc+yoPjB6ut7onUS9bWHfjZ67XnnNndZLe2KuXW+93LYfGFG1t21p1FnH8nMb6D/eZzqvzaBGbzQyg71RMerevT/TMn6M0wu9c+OWPtNpNbETnZ50fqanrQt7x0g4gJXPEHHkJokDuEGcuq8eLqGkGynpFuiy/A6T9Cvy+QNRfmB0btriVgVr+6xlD39ov/PSnnxBwe0FK1U4BMGkzQcc505ezLmaEnS+tN4ZyLc/JxF7o3yUuv/+3qYHXZu3fmi/N2yMVv92rt+MvWMmHMCYIM7cov4cQHH6rhYn8HxfnvZ8jh31B4YTcTlvtFs9N/tmJ+Knjp9W+3oRGx0yhknRcQjCkPdSdj4qFt2b6Xp1hzPbR2rJErcdlhn0uRyaGmDvaEubD+y/a457vYkT2L5sWaa7pS3TtXXnB9v1Y+OJp7B3DIUDGBPycQBl/xzROb71VHV19VH9HVsfGAcPuhdTVJV+bnVvNW+29t/668yB9OvWy1gOUjtXgr1t6sCBtzMdK1c5c1Lnut7aly5x0tguJ/auDB3oeSvTNu+unNeaRps7nngSe8dUaucw/Asoc/KMAM5NJpNNvvXOmpqaI0tfuvJgR/MZx7aMbbpl99gf7dg9tml7S3PT8zubm75uu1xQmbQ0n3WiXGMLRFt3Nzd1yHU3f1fz2f220wUohh3NZ4+U59pycfxS8pzbKNfbopYxZ+bVzhsAyhRx1E4V526daK1P6/xt+AqoAh7nW0+XstwAAAAAUEJyOYDi7NX718XhO1mjgLqcSCQkecPKgSwjAAAAAISEOHoTxZnbJrpPlk8zmwfJ+h5ZPyYr7U3iBI4Szayvr08OfGkBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoEAaGxsnJBKJQ2YwSCaT0xoaGs4UTZdlRpuvQMTuJ8jPETpdIEMGVR7cw/GC+zk+ZL+zudehGIbIxTJJLqYN/kGmZdtI2bZAl+V3mH9GEqgcxK4vi30Pih6tqampsl0eCA/u4fjB/RwLPvTO5l6HQGTPMmKmlDvft7/dTsmglIidm22XAUoD93D84H6OD/53Nvc6BCLbAZTlOaJzfOsprVawUzooFWa2mNPl96ra2trjbZcHwoN7OH5wP8cH/zubex0CkSMCOFe+KJp86501NTVH2ikdlJBB+k9VVdXRYv91tgsD4cE9HEu4n2NCVgSQex1yIxfDqfowEK31aZ2/nUAfVcDjfOvpgS43BKcP26tW1NfX/0D2zzZJB8u2d6wWFkKFezhemPv5VrPK/Vzh5KgC5l6H4sjhAJ6sXxW6nEgkZFfDSnulg1IgL4xviG1P0uW6urrPi42fsV0mCA/u4XjB/RwvshxA7nUoDvlymCgXzDbRfbJ8mm/7TXJRjTLtShhSoALRhsP65Si2/yW9BisP7uF4wf0cD3K9s7nXAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKJJY2Pj2HynEEsmk9dL2iXF/B3J+zX5W13F5AUAAACAEDEO4Np80hoH8KFi/o5xADuLyQsAAAAAIYIDCAAAAFAg4hBdIUqJc/MP+d0jjk6Tb99U0V7Z97r8PjJixIjPevtkW6vJu0mW/ym/y2traz8p+RfL8tuybYssf8FLX1dXN1S2LZV93aI2dcb6KpOke0zSzPeV4zbR032kPcQBlPVb9fh6PqKN/vnCjQO4Qrbfb853q39/VVXV0bJ+j6hdnT1Jf6dsHmLy4gACAABA9EkkEo3i7LzjzcOpTpo4ccfrsmw/VxyefTpRuzg/H5X1ebL+Fy+vOoCiDZL+M8cdd9ynZHmXaKek+7bsHiS/d/icNl1fr/O9yvJHNI86jnLc8bnKNWzYsGNlf4fs/74c81vqNGrZcqXNdgBl+RwtjywOluVLRD3y9z6m+9QBlPTvybbRul+Wm2X5TTnHT5i8K0QLhw4d+nFJe4zsf0rWp5u8OIAAAAAQfcShSagDKL9neE6Sh2x/VjTZW6+urj5KnacRI0bUmbzqADb70t8h60966+IwjZRtB0zak0Vp//Fl/49l2/N9lU0dSc2v0ThJ+73DnMNhq4Bl/xuS/0TzN9UB3JD1dzarQyj7qvX81Pnz5T1VI6AmLw4gAAAAVAbi2PxQnJw/a7WtaJVGBXW7LL+W7XhpL1jZf4pZbpX93/Ht+5Xkude3foKs/8v8jbNl/b/qjKk06iZ6S5ZfPUzRBpuo4o7DlT9HFfDlWnbzN1T/M1HJ3irgrPyPyrYr5bxOkt/3vTKacr6l/y8mLw4gAAAAVBYaATTVti/oel8RQElXq+uFOIDy+xWtTi6kPHLs63R4F43QyfKlfaXzO4AasRMdlPRf9O1/wytnHxHATRoB1Cpm+f2PbDqij/LgAAIAAED00Wif6Jvaxk9Wj5DfG8XJWa37tA2gVn9qG0B1DmX7XNGLXt48HcB/m9XBpg3gNTU1NUfK+iBtd+jvgOHHOIx/12IE1ggAAADwSURBVOpm7UiikTxJ/6Vcaf0OoKQ5XaOUprPKENn+c408ZjmA74lGmfP9iR5bO6+Yv6ttAOd563K84ZLmuyYvDiAAAABEH3HuviwOz19Nr12t9nzOqwIWBonTM00jdxpV0565w4cPr/Hy6vZ8I4CKOFOf1h7C2hbQVM1u8vc49tA2eLKvRR07b5tGIk118ZDs9FlVwFptvMCcj/6dK/zlNFXAy2Xb70wv4G3q2HnH0iinacu431T/bpPli01eHEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAcub/k63Nbr2TbXEAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9B5QkSXIduLMLgDhwIXic4QKzqqe7qgCShwOB44K37wiQxD0AxOPdI8Tt7MjWWmutq7XWWlRrrbXWWmtRWalli5md1djdmTo394io7OrKyowMYe7h9t/7XSo7wyJ+uru5u7nZl75EIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAguIyqqqofVVZW/mWR10QqKiraO7kOu8Zsxhx7rx+y9/r3Tt6rGNj7/xd2rS/Yt192833Ze/41s/8x+/oZ+zqZff2AfX3k5jUIBAKBQCAQmgVzQNqBo8McnknFXssclTbstYnmXlPIcXLqALL/+3+y9/15ixYtfr/c9ygE9r6rmX1rG10P7uPzL7nsAILzx967v5vvSSAQCAQCgWALzCG5yhydZ4xZ9uOvN/da9pq2jPHmXsOcm/9qOE5faXQdpw7gR8WuXQKavD+fHcBftmrV6q/cfM8S0KyuBAKBQCAQNELLli3/Izg5zNn5G1hdg+3IZl77n9nff8b4K9jyhW1Y9v378DdY8QOnhvGb7Pufwnuar2HvPRRe09gBbNGixR+x1+0DxxNWFdnfF7799tu/1dS12d/G5l+bfb1n2PS77D2Xwf83nNgD7HdV5v9jfxvDXn+O/X48+5piX+838d7DGH/B+M95Nn/DdAAZ/4n97gls2TIe/fa3v/0Hee//L2DllP0+xF7zkn09zfgfCjy/SsN2eM+fwnXY8/q/Gq+qvvXWW19lP9ew378Ah5ext/F8WhvXfG2FtfF7GA7tFvZ1kflc4Pff/OY332bfb2BMGs99A3vmbxbSnEAgEAgEQgABjgLjDeP7TcxpON/c6w1H47VVONMBhO/zVs7eaPR/LQfw61//+r82HJPe7Mdf+8Y3vvG/gnPFuNTOtcGBZL8/wd73LeZQ/qYRIxg3HUnDAfwF+90I9uNvwGsKPYcCK4BfsN+vA6fszTff/G14PvDavP9Xk+cUfpn9n+4QowiOaaH7MJ7Vfyt0X+z7VYyX33nnna+Bvezvyw3nNN8BfGVlson3WG38nzbsx68Y9/0bEGvI/jYVfoZnxN5rDdhfyFYCgUAgEAgBA3MCfo8N/j9hTkFn+BmcEnAsmPPyx4X+j00HsGAMIPvar7GzCathsAr5pUaOY6FrQyygcd3/Le9lv8Ze95y9/7vGdcYUi1k07C+4Bcx+//W834GD9wC+N5xYuH5Fo/d62txKav6zauK+3oBnwK7zt+bfwfE0Vj7tOoAX8q/Lfv6Hxs8C7g3sgZXB5p4PgUAgEAiEgAAOIsCWJKxuGb96w3BeFhf6P245gLA1aaxQfWKS/e4H4JDmb7E2d23mqH4HrtN425i97jr7/UDDljHFVjUNe0qKAcy3gX3/58YKYf49fMq+/ph9HdzMtQo6gOz3/wb+zvhvG93Tc7sOIOP6RtcdDPGHje2FZw4HbIo9IwKBQCAQCAEAxLUZTliaMQM0VgR/mOcUvgLmKHxczAFk//8vSlgBHM1+Pm7T3qZWABuvWH4FtpbZ+3/PuA6sAJ4t9t7sNSvtOoDsut+qFPGT37BzH6WsALK///c8O36n0Qrgn8F1YWUw7z2GN7EC+Mr9wP9nv6+1YyuBQCAQCIQAwTj0AYcR/hJWnfJYAauC7O89mvp/7PV/DQcYIGav0e8tpwYOOxiO0b/Lf02+AwiHReDQBGypsvf6X8zfsZ//ZyGbC8UAQgwb2A7vw14zE7Y5v/a1r/1L4z5LcgDZ6yYaW6ZfzvtdKSttOxj3gDMIP4NTBs4bxO8VulYRB9CMAbwIDi6sbrLvl+THABqHRH5grHKCw/gf4NkWcwDh/7HfRdnfxoNTCb+D52ZulxMIBAKBQAg4mBOwk/Fwgb/BQYrXTssagBU2OCzywthGfM/4P5/nOzWVDQmbPzG3Q9n34fxTwHBaF+yAFUhjK/K+cVijSTTlAEIco3EKOGlskx5kztcfmn8v1QFk/+fb4ACaW6P5p4C/1IwDaJwCHp13ShhO125vLldh42fV+D3zTgHDqWI43dyLMZvvqIGjDKt5xknsA3DSupgDCIDt9UpxcCVmOJFP2f+dX+z5EAgEAoFAIBB8hHFYB1Zr/xO2LQQCgUAgEAgED2DkUoSyel82ThrDiiuUinM1ITWBQCAEApDKAhLVNveaioqKIawz/UfGaruB2wQCgeAHWN/UivVndypFrWBIBg3JrSux7SIQCATZ8BsQsM46ymuVzRSjZ6/5LiRUhe+N3Fc7/DORQCAQCAQCgeA6jLxXBR1ASJPAnMCOea8vmhyWQCAQCAQCgSAxijmA7G/zKo26pcbP8UK5zggEE/fe+5/ffNrm+6tr27x742nrdxNP27y7/VHr730X2y5CMPGk9ff+c23rd5exz1yqtvX37z9p8/0Vta3/6U+x7SIEE48//t5fsc/biaetv/+QfeYesX5uxqPW//Cvse0iEGyhhBXAhflpFCD1RKHC8/n44osv6gl64rPTJ+pDXdrW17b5/mvMrVxS/8Xnn2ObSAgIoJ95uWdnk5+12g4f1v/g5LF66osIbuHzn/+sPj1/ZpOft7qubet/dOUStomuwC3/giA5StwCbp/3c6qU94UP0YsXP6x//pwYdILOpt7JA4esDjG2cF599t7j+lwoVp/YurU+1LWd+P2CefXPcj9At5voXG9MO549+6w+tmSx+Ly1/6A+sXlTffZJmH/m4jWrrc9hfN069GemMmXRG5vPsp/WR6ZM5J+pULcO9cnde+pztdH67J2H9dHZM8Tnrd0H9elzF9Ftdaq3G74FQQE0dgDhJF3+36FuJ6wCwvdGpYK9pbwvdBi80TwjBp2gMyBz9QYfiKEjTB459trrMjfv1dcaTiAMyth2E53pjd2+k3v3i0G3S9v69MUrr/09deY8XwWE16TOXEB/bqpSFr2xGVu0UDh/vbuwiUbktb8ntmwRn8eOH9enb9xBt9eJ3u56GQQpwZy9bkYVgRr2/X/9kiiPFDLLHeW9bhJULmCcAiWvSnlv6jD0Iej8qx//qD7Uo6Nw7jZsLPja9PU79bVt32MD80f12adRdNuJ5emN3b4zD0N8oOXO3dmLBV9nOomhbu2bHLSJauiNzfSFK9ZkI3PnYZOvyeU+q4+tXCm2gwf3q89lPkG3u1y9vfA3CBpB9w5DJ3KdN9Twjg+2SKAjbO715kw6Om8Ouu3E8vTGbN+57A/qw6OHi3CCpUuafy37LEbnzBKfzelT0J+disTWG5vwGQqPGsY/Q4nde5p/bebT+rphA8Vrt25Dt71cvbH9B4Li0LnD0I3ZB0/E1i8jrMwUfX0oUV/bqTVfCczcfoBuP9EesR2C1PFTYpVlQK/6XPJ50dfnYlkr/jR97Rb681ON2HpjM3X6nFhF7tu9PpcuvqoHnzFzK1jFVWdyAAmOoXOHoRsjUyaIrd/Vq0r+P/H168WqzIRx6PYT7RHTIYDVv7rBfUWc6dHjJf8/WI2B/xMeN6roCjVRHr2xyT9vxooeHHAr9f9FFy0QK9RLFqPfQzl6Y/sPBMWha4ehGzP3nojVmB4d658lciX/v1ziWX2oZ2cRw3WucAwXUT5iOgTg9IkYq758cC71/+VSL+pDvbsaMYN0IEQVvbGZOnZSfN4G9ubbu6X+v+zjsIh17tymPhd/hn4fdvXG9h8IikPXDkM3xlau4B3k803rbOud3CcC9OuG9Lc1mBNxieUQwMpd3SCx+gcDs93/n9izz4pTxX6GKlFXB5Cv/g3qY3u12aSZMiaxZy/6vdjVG9t/ICgOHTsM3ZhLv+T5sKCT++d0yrbePGDa3M47fBT9foilEcshSF+92RD7V8aEAVZi+Mnhdu/zOFTs56gKdXUAkwcPO5qgQuoh/v+HDlAq7IAcQIJj6Nhh6Mbk0RNWXFW5epvvEZkwFv1+iKURyyGILV4kYk03Fk4zVIxw8lzlE5o66Y1JvvrXv6dYbT55tuz3CPXrIQ4fXbmJfk929Mb2HwiKQ7cOQ0eGq8eKDvLw0bIHCIjNqu0sTgTTqowaxHAI+GqzcZIX4qvKfZ/0pWsNMYQKrcropjc2rdXmQc4+J4ktW0XKqzmz0O/Jjt7Y/gNBcejWYehGnogXUh2wQflZ+oWjASI6d7ZYldm5C/2+iMWJ4RCkTpwWq81jRzp6n1dWZa6rW60h6HpjM7Z8mZHUfoOj98mGU/W17T/kzIaT6PdVqt7Y/gNBcejWYejG+BqR+Dm2bKnjAQIqOfDBfdQw9PsiFieGQwBJnHms6L79jt/LTEEEW8rYz1IF6uYA8klCry78M5K5/8Tx+5kT3PjmLej3Vqre2P4DQXHo1GHoRihxZKZwydx+6HiA4O/XXRwmyT6qQ78/YvP02yHIRjMi0XiHD3lSZ8fvByk6jLJeudRL9OcpO3VzANOXr1uHN1x5v6u3GhJJK5DtgBxAgmPo1GHoxtTJM2LFbuRQq8NwqjckTOWz5E2b0O+P2Dz9dgggjQY/KDRzmmvvGa4eU3Z6D92omwMYW7bE1b6Ipy9izmSxutWykBxAgmPo1GHoRrPyR3LfAavDcKp3+soNq4g69v0Rm6ffDoFZ9zd1qrzTmE0xeeiocConUiUa2fTGJN/+NXc3HtS69r6JbduVqQxCDiDBMXTpMHQj1F41g5rNDPduDBC84+3TTXS8dx6i3yexMP10CMzDRpBvspQ6rKWSf447txGnz59G0Z+pzNTJAbROiQ8f5Or7Zu4/bdgGlvz0OTmABMfQpcPQjWZh9Pwavm4NELHVq8TWS00N+n0SC9NPh8A6sLF0ievvHV0wj06fS6Y3Nq1QFJcPbPBtYCOvYObuI/T7LKY3tv9AUBy6dBi6EQZiPmhu3/FKh+GG3plb95WZJetMPx0CsxRX+vpt19/bTC0DIQ3Yz1Rm6uIAQmWiUI+Owkl7GHL9/SFjggpJyMkBJDiGDh2GbuSz2H7GLPZeQ3oEtwaI/FqvcHIO+36JTdMvhyD7JCImBD07ezIhgBPFUBYOysNBomns5yordXEA0xeviMNtIwZ78v6pcxetyknY91pMb2z/gaA4dOgwdCMERTe1QufmABFft05swbCv2PdLbJp+OQTJ/QdFFYW5sz27RnjMCDHhuHgV/bnKSl0cwNjihZ6u0EHKIbMWtRvpjLzUG9t/ICgOHToM3QixUiKB7sLXOgy39DaDsGFgxr5fYtP0yyGIzp4pTpsfPOzZNaDSA8WdyqE3JmFCG+rV2Sg16F0u0sjUSeJE+7GT6PfcnN7Y/gNBcQS9w9CRkcnVTRZHd3OAgK04MUv+oD6XeIZ+z8TX6YdDwE+FdxfxWNnamGfXgdhCL059Bok6OIBQ8YN/Dgb08vQ6iT37xKr2vDno99yc3tj+A0FxBL3D0I251IsGxyz+qmPm9gABudm4o3nmAvp9E1+nHw5B5vYDIy9kX0/vhTuaXdsJR1ORWq1B1Bubid0i2Xhs0UJPr2PFtfboKG1VEHIACY4R9A5DN1oBzONHN9lhuKl3YstW0RmvXIl+38TX6YdDYCXOXb7M8/uJzpwmtpoPH0V/tjJSBwfQ+gz4UBmmbkh/EXd64w76fRfSG9t/ICiOoHcYujG2YrkIkGbOWVMdhpt6p2/cFas/wwai3zfxdfrhEEQmjherwKfPeX4/UNFG9m25oOuNSRFuYNQiDyU8v168ZrWIO12/Hv3eC+mN7T8QFEeQOwwdWTdQ5GPL3H69SofbAwR0yLXmtlwkhX7vRG/1fk3//DjQuPdxoF6nm1GdQXcAofIQn3AO8jbcwGT68nWjlvoQ9HsvpDe2/0BQHEHuMHQjnIrjA2SvLk0OkF4MEJHpU6Q/LacrvXYIICULHyDH+ncS3Ew43dQER3cG3QG0shv4VKcXEk5bE9w6+eJOyQEkOEaQOwzdmNgjAqShdFahDsNtvRO79hgpZxah3z/Re73zGV+zxvctMog1VKFKQxD1xmZk2mQx2Tx+yr9rGjGHMk5wyQEkOEaQOwzdaHWQBTorLwYIqDTiR1oGon167RDA1pioBnPTt3uCE+eixvVY9OcrG4PsAL5yCtzHcJPEjp2+HXIqR29s/4GgOILaYehGniDVDJAON91BejFAvJKY9WkU/TkQvdXb0j2aqa9t+159bec29bnMJ77dUy75vL62/Qf1tR0+5N9jP2OZGGQH0Kw/Didz/bwunAD2suycU72x/QeC4ghqh6EboSh6sZU4rwYIKAHGUzMcOIT+HIje6w2EbTi+Ejd1ku/3BSmO+MrjhSvoz1gmBtkB9DPdUD5hcmOVhZNswkEOIMExgtph6EYow1UsRYZXAwQ4fl7XgiXap5cOAcR88li8nbt8v6/42rUi9nDjRvRnLBOD7ABGpkw0qhud8f3a1oRDsjrU5AASHCOoHYZutAbkPfua7TC80NtKz1Hg9DERh146BHWD+4nTuHcf+X5fqTPnxerjlAnoz1gmBtUB5Kdxu7TlIQcQeuD39eNrjcNOmzahP4vGemP7DwTFEcQOQ0fWDR0gBuQ7hdNjeOoQDOglrn//KfqzIHqrdy6eE/F/bFDGKJOVjaTFhKNbB5pw+KA3Ns04PKw60NbBo8nV6M+isd7Y/gNBcQSxw9CN1oAMAfnNDMheDhCQeobiAOWiV3pD7B32SVxrwvGgFv05y8KgOoDYJSf5gSd2fcgJKFNdYHIACY4RxA5DN6bPXzYG5HFFOwyv9IatZz+TtBKL0yu9YSuMb4mtXYN2bxDryicch46gP2dZGFQHMDJ5gm/lBgsRM+ShOb2x/QeC4ghih6Eb4xs2iAF53bqiHYZXeptpGmRMl6ArvdIbTv5iD8iJ3XtpwuGT3tgM9eiEXm4ytmhh0RhrDL2x/QeC4ghih6EbI5OqxYB87mLRDsOzvHBWuoQP6nOpl+jPhOhh3kdzQA7jlcey8sIhxYXJyCA6gNlQXMR79umGakcpWRYw9Mb2HwiKI2gdhm6EmBR+Qo51TrlYtmiH4WlliDEjjMoQt9CfC9EbvbOPw2JA7tcD9d74yVBJ87MFSW9sWgcwEPJN5tPKs9q/J/ozydcb238gKI6gdRi6EWJSeMc0uF9JHYaXesdWLBfbJDt2oj8Xojd6J4+eECshs2eg31943Cgx4bh0Dd0WGRhEBxByPfpdb7opipXvjmLluw5v5bux3tj+A0FxBK3D0I3JfQfEgLxwQUkdhpd6W87BnJnoz4Xojd4yOfnxmhphy5Yt6LbIwCA6gJHpU0V4y6mzEtgyRdhy4jS6Labe2P4DQXEErcPQjXbSr3g9QGQf10m3TaIzvdA7PHq4WHW7hr/Nnzp5VmwPTpuMbosMDKIDGOrbXZo644mt24x0NCvQbTH1xvYfCIojaB2Gbqwb1MdIwPykpA7DS735Nkn3DsaJvTT6s9GdbuudS39SX9vhw/ra9nIc9IGtOB6P2KMTJYT2QG9smvn3oE+RQV+IbeaZDkYNQ7fF1BvbfyAojiB1GLoxa3aQ3dqXlKDUjwHCytl1tvkTyUTv6bbe6Rt3xQA4cgj6vZmEwyh8wvE4jG4LNoPmAELt3VLym/rFXPpl3gToBbo95AASHCNIHYZubChRVFpNVD8GCCsnIfuK/Xx0p9t6J3btFltgy5ai35vJ6OyZIgTiyDF0W7AZNAcwsW27+LytXoVui0krBOL6HXRbyAEkOEaQOgzdaLdIuR8DBKz82XFKid7Rbb2jc2cLZ+vwUfR7M5nYuUs4CcuXoduCzaA5gNE5s8Tn7egJdFtMQuJxkRB6L7ot5AASHCNIHYZutBJAn79ccofhtd4Q+ydT3I7OdFtvq/7uwxD6vZlM37hjbEsPRbcFm0FzAOsG9TXqPT9Ft8Vkcr/IugCVQbBtIQeQ4BhB6jB0o90SSX4NEHAKWMRl1aE/I53ppt6WY99NLsdeHEz5SJqDKUHRG5uQ3Lu27Xv1tZ1blxTf7BczN+9JU/KSHECCYwSlw9CNVomk3l1tdRh+6A15AGXbutGRbuqdOmsv3tRPwqlMHpd14y66LUHRG5uQZog7WmNHoNuST34QhE024DAIlL/E1hvbfyAojqB0GLqxnBJJfg0QkCSYb5OsWI7+nHSmm3pDJQZZD/eYcVmQFB3blqDojc3E7j3SxnZC/Wm+NX37Ibre2P4DQXEEpcPQjXDwgw/I69bZ6jD80NvKlzVGrtm7bnRTb5hoiPQ+F9DvqzGTe/cLZ2HpEnRbgqI3NqGyUakJ7n23zUy+f/Awut7Y/gNBcQSlw9CNkZnTbJcl8muAgFis2nYf8Ngs7G0Snemm3qE+3URcZyiOfl+NCSk5aMIRLAewYZXtAbotjZnYJcfqJDmABMcISoehGxsOWpSeANfPAcLqwO/gbpPoTLf0thKOd+8o1QEQk7IeGFBVb2zCpLG2/YecMk4g01dvGvGJI9H1xvYfCIojCB2GbszFc7wDqu3aztaA7OcAEZ0/V7qccbrRLb3Tl65JVZGhKVopQyRKUaOq3tiEVT9ZTto2xYYJRxvUCQc5gATHCEKHoRvTl6+LDnL8aNsdhl96WwdBVsmTxV83uqV3g5Yr0e+pEM2KIKnjp9BtUV1vbELcH2gZXbQA3ZZCtGqwP6hF1RvbfyAojiB0GLrRqn5g85StnwOEVcdzoryrRkGnW3pbq7mH5F3NTWzZKg5FrV2DbovqemMTSg3yahu796LbUohWqqtjeKmuyAEkOEYQOgzd2DAgH7HdYfilt5U4uGdn9OelK93S24rnvPsI/Z4KMXXukphwTJEvT6FqemMTDvPwvI7XbqHbUoiJrdvEhKNmNare2P4DQXEEocPQjXXDBpY1IPs9QIR6dxEHVcJJ9GemI93QW/aAfJPZuqSRGL0Lui0q641NiKmr7dSax9hBrB22PYWYvngFfYeDHECCY6jeYehGXvqqzEz0fg8QUDXCTq1iort0Q284xQ0awiog9v0UY6hXZ2PCUVppxKAxCA5g5v5T8Xkb3BfdlubYcDIerzQiOYAEx1C9w9CNmVv3yz4h5/cAEa+pEbE827ajPzcd6YbeEPfHA/IXzEO/n2KMTK4WW4eaTjiC4AAmjx4Xn7e5s9FtKcZQ3+5iwvE0iqY3tv9AUByqdxi60ckJOb8HCJU68yDSDb1jK1cKJ37HTvT7Kcb4GmPCsXUbui2q6o3N2OpVykwaI9OniB2OU2fR9Mb2HwiKQ/UOQzc6OSHn9wCRufdEbOcMHYD+3HSkG3pHJowVq2qXrqHfTzHCiUw+4ZgzC90WVfXGpkqft/jGjeIgyPr1aHpj+w8ExaF6h6Ebw2PLPyHn9wCRy3zKYxUhZhFiF7GfnW50qjfENkH1D/i85aIZ9PspxswDM36sH7otKuqNTf5569ZBfN5iWXR7ijF15rw4CDJ1Epre2P4DQXGo3GHoRn5CrnP5J+QwBgiIVRQ1PakknN90qne2Ni4C3ft0Q7+XUmidIG33fn0u9QLdHtX0xmb2SUR83vr1QLelJHtDuO2DHECCY6jcYehGKHPFVzgG9Sm7w/Bbbzg8UE7OQqJzOtU7dfYC6gpHOQyPHi5WyG/cRbdFNb2xmTp5VnzeZkxFt6VUWivkCCuW5AASHEPlDkM3po6dFDFOs2eW3WH4rbcKZcSCSqd6xzdvETFO69ah30upjC1ZLCYc+w6g26Ka3tiEWDr+edu0Cd2WUhkeNwotaTU5gATHULnD0I3xtWvFAZAtW8ruMPzWG4K5+ax+ApWE85tO9Y7OmqFcfd3k3v1iwrF0CbotqumNTVhp5p+3sxfQbSmVscWLxIRj/0EUvbH9B4LiULnD0I2R6VNFB3n6XNkdht9658yEqT06oj8/3ehUb6vg/cMQ+r2UyvT1OyJP5pgR6Laopjc2Q727irx6oQS6LaXSqsu+0v8dDnIACY6hcoehG+sG9XU0IGMNEBAkzTv2OioJ5yed6A2HjOCwERw6gsMV2PcSdLux9cYmVG/hE8VeatUOT18wSsJN9r8GNTmABMdQtcPQjbwmazsoAfdR2QMb1gARmWKUhDt3Cf056kQnelsraaOHo9+HXdYN6CUmHE8i6Laoojc2oW/AcqSc0DoJ3Lc7it7Y/gNBcajaYehGN5IqYw0Q8TVrtK7QgEUneif3GbF0Sxaj34ddWrFk5y6i26KK3tiEuGZ+AGTtGnRb7BByF9Z2aStOApeRmsup3tj+A0FxqNph6MbUidPGCeAZjjoMDL11r9CARSd6x5YvK7viDDatcmIKlK+TRW9sRmdNF0476+ewbbFLM/VQ5uY93/XG9h8IikPVDkM3QmoEPkPesNFRh4Ghd+a+sXo5pD/6c9SJTvSOTByvTEmuxjTrZccWLUS3RRW9sWlt2z+uQ7fFLqML5xu5To/6rje2/0BQHKp2GLoRVs+cpuTAGiB4hYYOH/EYRohlxH6WutCJ3iof3Elfvy3iF8eORLdFFb0xmYvnuF61XdvxLVVse+wysW27mJyvqfFdb2z/gaA4VOwwdGTd8EFim+HuI0cdBpbeELvI7b//FP1Z6sJy9c4lnonAdkUHZKjKwO3v3gHdFhX0xmb68nXhsI8fjW5LObQq5kyb7Lve2P4DQXGo2GHoRr6C1vFjUeM0Xf4KGuYAYSUVPnkG/XnqwnL1hlgmVU8Amwz16iJWMCMpdFtk1xubDbn0VqDbUjzHHjAAACAASURBVA7NGsZ1A3v7rje2/0BQHCp2GLox+zhsdDDl1QDO7zCw9LbKPG0ur4oJ0T+9k4ePikM7C+ah30O5DFePFTGMV26g2yK73tiMLV4oYugOHEK3pRxaE/S277EJ+ktf9cb2HwgK40nr7/X/9MgB5ToM3Zg6484WA+YAkTxqnASeNwf9eerCcvW2Sg4qnLYntmyJURN4P7otsuuNTdj6xaqn69o9jBgsQlzuPPRVb2wfgqAwnrb+/nOYtTzzcdZCtE+3gowxB4jM7QdiW3HUUPTnqQvL1Tsyw1nJQRmY2L1HbCuuWI5ui+x6YzPUs7PIoxfNoNtSLqNzZ4sJx7ETvuqN7UMQFEZtm3dv8DiZe4/RGxCxmc7FpTQDmANELvVClOjq0lbJgwUqsly96wY7KzkoA9MXr4pV80nV6LbIrjcmrQM7PTqh2+KEENrCJ+nr1/uqN7YPQVAYT9u8u4nP9E9RYL7MdCvRKPYAEerXwyj2Hkd/pjqwHL1zmU/ra9tDycEPla6lmw0l0Ep0qaQ3Nq2UPeNGodvihKmTZ0WIy8xpvuqN7UMQFMaTNt8fJ2J9tqI3IGLT5KWGurZzpdQQ9gARmVwtYn0uXkV/rjqwHL0zD54GImm3m+1GFWK373KYPHhYbNUvVjtpd+ZBrWg3g/v5qje2D0HwARUVFUMqKyv/kbGaff+NQq+rqqr6E/blK2+99dZXW7VqVVHsfWs/+v6HvPEtnI/egIhN082VDOwBAuKxVC0vpiLL0Tt1yv+VDK+IVaJLJb2xGa+pCUTZPr5y3uFDvnoO3/ult6uOBkE+MIfvu8yxWw7fs69fZ07gjkKvZX+7xV7zgnHX22+//Wax937y4fe/o2PGfJWYvnjFtVgm7AEiuXe/mO0vW4r+XHVgOXonthixTOvWodvvlJDGhsfOHva3RJdKemMTMhvwMKSzF9FtcUpYNfcz2T05gBqAOXPDmRPY0fyZOXmJZl7b2s573/r7v/89vrrUU+0A3CAzscu904zYA4SZ8T8yYRz6c9WB5egNaXq403T0OLr9TglpbLgzu3YNui2y6o3NukF9jBrAYXRbnNJKdn/itG96O/EtCAqAOXzzGN/P+zkOW7xNvZY5gFNatWr1d+zrsBYtWvxRKe8f7iWO4D+LZ/kHiigXY0uNfGb7Dzh+rxcvxAABXzHuJRdJie3sPt3Qn6sOLEdvSNPDVzFu30e33ynTZ86J7ewZU9FtkVVvTD7LfsLrg0Od8Ge5H6Db45SJDRvEdvbmTb7p7ZafQZAUzJlbWFFR8W7ez+m33377twq8/A3458033/xt5iheKuX9ExNFEs6fhUP1BPmQnDKe6/PTp4+xTXGML774or6uewd+P5//7GfY5hAagevTtS1P1/P5z3+ObY5j/CKXEQ7gsP7YphCawD+nxYQwNnIwtimu4EdXLonJ05L5vl3TBReDIDOMLeD2eT+nmnpdq1at/p79babx45eZA/iTUt4/u2KxWLY+cgx9BkV8nVaS1FjGlRkjAHOFIDzGCMy/dQ/92QaddvXO1cXFSca+3dFtd4OwqsQD89t9wFebsO2RTW9sps0DR7NnoNviBrP3HomUNsMH+aa3Cy4GQWYwp+7PYRUQvm/ZsiXz6yr3wvfMKWyV/zrmAP4V+/t34Pt33nnnD9nrjpby/p/s3+17AktiaYTM+G4mSYVOAwBfse7JSmqtSWA+Ju3qbR04mhyc5Ml1QwcYgflP0G2RTW9sWgeOAjL25NKwpf0+rwvsRw5N0Nltf4MgIZizN4k5ge8ZMX6Q3uUN5uCF2O9/p9HrOsJqIfvb+FJOAQN+dP2KMQubid6AiK8yffWmmFGOH+1ah4E9QDQE5q9Ff75Bp129rQNHK1eg2+4W/Q7MV0lvbEbnzw3MgSOTDYda6nzR2xOHg6APfp4U2z5QzBq78RBfJRz84APyksWudRjYAwTUl+WrTDOmoj/foNOu3rFlxoGjffvRbXeLsLrEJxybNqHbIpve2AyPGmaEg9xHt8UtRqZPEROOM+d90RvbfyAojs//+Z9FjdbObahGq2SMrVwpTpXt3OVah4E9QEB9Wb8z5utKu3qHq8eKSi1XbqDb7haTx06IHY65s9FtkU1vTAa1UgukHBLVtbb5oje2/0BQHNBhQNC3qNGaQG9AxAZGJk8QA/KFK651GNgDBMTG1Lb/kNOvjPm60q7eod5dRD8QSaHb7hYzdx5qs8MhQ/suldm6pJUSCtsWN5k8ckxMOBbM80VvbP+BoDigw4hMHCccjcvX0RsQsYEh0zGvjbvWYcgwQFgZ8x+G0J9xkGlH71w8Jwbk7h3Q7XaTufRLscPRqbUvgfmq6I3N9KVrIhRkYrCSwsN2Np9wjBrqi97Y/gNBcUCH0RD7cwC9AREFYVuED1xd2rq2NS/LABGZOU3EyZw+h/6cg0w7eqev36kPalnIugG9xETqSQTdFln0xmZizz4R37x8GbotbtLqt30IqSIHkOAY0GEkd+0SjXHVKvQGRBRsmEkOc7XDkGGAgBPAfsXJ6Ew7eicPHhZbV4sWoNvtNiNTJ4kJxzn16826pTc2obQl7wN270W3xW3W9etp7NzEPNcb238gKA7oMNLnL4rl+GmT0RsPURDy5LkdSyLLAOFnnIzOtKN3vKZGDMjbd6Db7TZjq1eJe9uxE90WWfTGZmRStQg7ungV3RbX722KiN1Onb/sud7Y/gNBcUCHATmL+MnMQX3RGw9R0IvTZLIMEJmb98Tq5ujh6M85yLSjN0z++KB19gK63W4zeeCQ2OFYvBDdFln0xqYV3xxyJ75ZJsJOmh8TDnIACY4BHQYvmcRPZn4Q+EBpVRiZPtX1fFKyDBC5xDNx4KBrO0o95CHt6F030ExgG0a3222mr98WE45xo9BtkUVvTOZSL1yPb5aJfk04yAEkOIbZYdQN7isGgEfeZzAnFqeVUd5FPWQaICD9A7+/cBLdlqCyVL39LmHlN3OxrHHCuSO6LTLojc3MbSM1z0jvT8pi0K8DVeQAEhzD7DAatoCCHSitAnOZT3gB+9oOH7k6IMs0QFDqIe9Zqt6Ze09ECMiwgeg2e8VQLzPHYRrdFmy9sWkl5543B90WL2ilVOrW3tMVTnIACY5hdhhWoLRLVSeI5dOrAVmmAQLSP/DP25596LYElaXqDXVyg14PPFw9JnBVTsrVG5vxDRtEeb7Nm9Ft8Yqh3l093+EgB5DgGGaHYdWdXboEvfHoztTxU54MyDINEJD+gX/eVixHtyWoLFVvqJPLB2Q2MGPb7BWhXwtaneNy9cYm9Gt8t4lNPLBt8YrWDsela57qje0/EBSH2WHAVhxPBTMhWJnZVWR840ZjQN7oeochywBhVQKYVI1uS1BZqt5QJ5cPyMdOotvsFRO79gR+wiFT+26OdcMHiUpA956g2+IVrR0OD/MckgNIcAyzw7BqM/btjt54dGd0jjFDPn7K9Q5DlgEC6k7T581blqo31MnlA/LdR+g2e8X0xSuBn3DI1L4LkdcC7/gxP3QEh4+w7fGKyb37xYRjmXc7auQAEhzD7DAgWBWO5cPx/FzqJXoD0pkQ+ydmyI9d7zBkGSBe+bwln6PbE0SWojfXoVNroUM6uO0e8s0FfcIhU/suqMOTiIhvHtgb3RYvCbGm/CRw9VhP9cb2HwiKI7/D0GElQHZ6OUOWbYCAgun883brProtQWQpemefRsWAPKAXur1e0ppwsHsN6oRDtvbdFFPnLomV2KmT0G3xknDanE84enX2VG9s/4GgOPI7DGvrMcDBubLTqsoysI8nHYZMA0R0/lwRmH/0OLotQWQpelsD8pSJ6PZ6TairzSccN++h24KlNzYhywTfGl0d/LrzoR4dxYQjmvFMb2z/gaA48juM+Pr1InB1yxb0xqMrofIHH5CnT/Gkw5BpgIDPGT/ssm4dui1BZCl6WwPyquAPyFB7mk84Dh9FtwVLb2zGliwWGhw4hG6L1wyPHy1OAl+96Zne2P4DQXHkdxjJI8dE+hHWUWI3Hl0JtX+5U7RmjScdhkwDROrkWfF5mzUd3ZYgshS9Y4sXaTMgW21rrfttSwbK1r6botdOkUy0nN39BzzTG9t/ICiO/A4DtkZECZsR6I1HV1qrFIfcX6WQbYDI3H8qtruHDkC3JYgsRe+GAfkWur1eM3X6nLG6PhXdFiy9sQkxcUGvyGIysWu3WF1fucIzvbH9B4LiyO8wrBI2PYJdM1NmehmnJNsAwUvetXe/5B2xdL1DPTp5GqckEzMPQ2LCMagvui1YemNSl5rMJr1OPUQOIMExGncY1oDAGit2A9KNXp9UlHGAgMGYrwg8qkO3JWgspjc4fWLC1wndVj/IT9h3+JDX2YbJB7Y9fuuNzfT1O8YO00h0W/ygdcK+f0/P9Mb2HwiKo3GHAY2TbwnduIPegHSj17nKZBwg4LALP3l+5gK6LUFjMb1h25cPyONHo9vqFyHcgK+w3w9eFQoZ23c+kwcPi5jfRQvQbfGDr6T08mDCQQ4gwTEadxjRhfMDfVJOZqYvXvV8y0C2ASK+pkacPN+2Hd2WoLGY3sn9B0WM0uJF6Lb6xeisGYFNdSVj+86njm29bkh/MeF48NQTvbH9B4LiaNxhJLZspdQcSLTKBy1f5sn7yzhAJA8d0WpVwE8W0xtSv/ABeecudFv9opnqKr5pE7otfuuNTR1X++HAkbjn857oje0/EBRH4w4jdfKMGJBnz0BvPLoxtmqlpwOyjAMEhBrQyXNvWExvSP7MB6fzl9Ft9YvJYydE/zZ3NrotfuuNTR3jfeM1q0WfvmOnJ3pj+w8ExdG4w4D6szxwdfgg9MajGyPTJosB+exFT95fxgHCOnnevQO6LUFjMb0hOJ0PyE+j6Lb6xczth2LCMXIoui1+643JhhP/H2p14h9yAPJdnSWLPdEb238gKI7GHQYUhIfC8LWdW/NTqdgNSCfWDRYzZEhX4cX7yzpAhHp1MXKDpdBtCRKb0zuXMtp5J73aOZyu5xOOru3QbfFTb2xCDBxfWBjSH90WP5m+fF3EdU8Y54ne2P4DQXE01WGE+vUQA3Iojt6AdOGrKSo+9eQasg4Q4eqx4uT5lRvotgSJzemduWOshI0YjG6n32yYcAQrGbGs7RuYOmVU/Zk5Dd0WP+llZgdyAAmO0VSHEZk4XgzIl66hNyBdmH0SETPkgb09u4asA0Rs6RJx8nyfNyWTdGVzesMpWD4gz5mJbqffDI8bJfq3a8GqfiJr+wZaZfg0O1zIc7t2bs1X22F3zW29sf0HguJoqsOILVtqDMj70RuQLkxfMLLGT5ng2TVkHSAaSiatRLclSGxO78SWLWJAXr8e3U6/GV24wLNyi7LqjU2rxOWRY+i2+M26YQNFaM89d3NPkgNIcIymOgxrQF5FA7JfTOzZK575iuWeXUPWASJ9/rJwfid75/zqyOb01jnfZ1BTXcnavoHh0cM9K3EpO2Hbmx/uO3XWdb2x/QeC4miqw0iduyQG5KmT0BuPLoSC4TxdwO49nl1D1gHCj+1vHdmc3tY26PXb6Hb6TWv7e3awtr9lbd+wDQqHbniJy8QzdHv8ZnzNGk8SYJMDSHCMpjqM7OOwUTS9D3rj0YXgbPNZInO+vbqGtAOEDwdgdGRzelsHIaIZdDv9ZlAPwMjavrPhlDgI0acbui0YTB44ZFTcWei63tj+A0FxNNVhWANyexqQ/SI423xAfuxdklRZBwh+/4P1SxLrNQvpbaVC6dYe3UYMmvdf26VtoFLgyNq+G1KhjEW3BeX+r9wUE47qMa7rje0/EBRHoQ6jbnA/T3PSERvIHe72H3J6mSRV1gECaCXBPudNEmwdWUjvICdDLpWh3l0Dl3tS1vZtrYB5kAxZBWbDSU9WQMkBJDhGoQ7Dqtt4Vp+6jWgdxOM6X7bcZR0ggHACmMfJ7NqNbktQWEjv1PFTRgqYWeg2YjE8frSIgbwanFQwsrbv+Joa0ba370C3BYM8FUyXtiIGMvXCVb2x/QeC4ijUYXhZw5D4Kv06dCPrAAFM7NknVgmWL0O3JSgspHd8s74pYExGFxmpYA4eRrfFa72xaZ2CPX0O3RYsQrwp31G7+8hVvbH9B4LiKNRhJPcf1HrZ3k/CyV+RB2+Fp9eRdYAApi9eoVQwPumtcwoYk0FMTCxr+7by4N13Nw+eSozOniGc4BOnXdUb238gKI5CHQaU5dI5cNdPQu4/vtq6Z6+n15F1gABSKhj/9G5IAXMH3UYspk6eMVLBzEC3xWu9MellJQyVCBMN3sdv2eqq3tj+A0FxFOowvApcJb5OqP7BB+QLVzy9jowDhElKBeOf3qFenUU8koYpYEzCVlzQUsHI2L6zoYRntXBVYvLQETHhWLjAVb2x/QeC4ijUYXgVuEp8nbDqxU8kPol4eh0ZB4hXngOlgvFcb91TwFjPgfVpQUsFI2P7pp0k4zlcuyUmHONGuao3tv9AUBzNdRjhkUNE7Madh+gNKKiE1S5Y9YLVLy9TwJgdhmwDRD4pFYz3emduPxAD0Sh9U8CYhN0NPuEIByMVjIztW/cUMCazkbSYePXq4qre2P4DQXE012FAmgg+IB8/hd6AgkrIs8hj3wb39fxaMg4Q+aRUMN7rbaWAmTsb3T5sQmJekQrmJrotXumNTa/KoKlIqxxe8rlremP7DwTF0VyHEd+wQZyU27wZvfEElamzF8UWybTJnl9LxgEin5QKxnu9KQVMA6E0V5BSwcjYvikFTAMh8TrfUbv9wDW9sf0HguJorsNIHj0uVgvmz0VvPEFlYucu4fSsWun5tWQcIPJJqWC81zu6YJ5weo4cQ7cPm1YqmLVr0G3xSm9s1g0fJJyee/qmgDHp9o4aOYA+o6qqKsOYLkZsO+2guQ4jc/OeiBcaMwK98QSVsNrFB+S9+z2/lowDRD4pFYz3eofHjhTbnjf0TQFjMnXyrJjgzpqObotXemOSUsC8Slh1d3NHjRxAn1FRUfFfSiG2nXbQXIeRiz8TgavdO6I3nqAyMrlaDMgXr3p+LdkGiMakVDDe600pYBqYufdYTDiGD0K3xSu9MZmtS1IKmDzCqjufcCyY55re2P4DQXEU6zBowPCWdQN6iZOIT6OeX0u2AaLJ50GpYDzTO5cwJnTdOqDbJgNzqZd8daq2c5tApIKRrX1TCphGz+PGHbGjNtadHTVyAHHxG5WVldWMdYyfwS8qKir+tqqqqie2YXZQrMOgqgHeMZf5pL623fv1tR0/9jwFjNlhyDRANEVKBeOd3plb940UMMPQbZOFsDrFJxx1SXRb3NYbm1YKmMWL0G2RgblYVkzAenRyTW9s/0FbMGdvPnP2DjH+BXMAfwC/a9Wq1TfZ9/exbbODYh2GVTT9kL51Q71i5kGt2IIa0t+X68k2QDRFOAxDqWC80ZtSwLzOcPVYMcG9cgPdFrf1xialgHmdoe4dxI5aPOeK3tj+g7aAwx7MCfwd4/tPzN+bzqAqKNZhBLFouixMnbkgtkimT/HlerINEE2RUsF4pzcEn/O2vGEDum2yEFan+AT3wCF0W9zWG5twuIav5p86i26LLAyPHi5ORd+854re2P6DtmCOXuJrX/vav4TvTQewRYsWv8e+j6IaZhPFOgxovOKkXHCKpsvCxI6dwtlZvcqX68k2QDRFSgXjnd6UAuZ1wuoUd4rXqJ8KRrb2TSlgXmd03hzRBo+ecEVvbP9BWzAHcAnjSnACDQfwK+znRYxzsW2zg2IdRub+k0CdlJOJsaVLRGew74Av15NtgGiKlArGO70pBczrhATFfII7cxq6LW7rjUmRAqaNSAGTohQwJuMbN4oJB/vqht7Y/oO2ePPNN3+bOXs7mPP3C/b1c8afw89vvfXWV7Fts4NiHUYu/Yk4KdepdSBOysnEyMTxYkC+dM2X68k0QBQipYLxTu9QT+NEfyyLbpsshNUpPuEYNhDdFrf1xiSlgGmasPLHJxzz5riiN7b/oD0qKireatmy5Xfeeeedr2HbUg5K6TDq+vUUJ+Vq4+gNKEj0+7nKNEA0+1woFYzrejfk9KQUMPmEBMUiFYz6E1yZ2nf6yk1x4ryaUsDk0yquMHq4K3pj+w9agzl+v1tZWfkB4yD4CjGA2DbZRSkdRmRSta8rVToQY2VVpgGiOVIqGPf1phQwhWmlggkl0G1xS29sWygFTNN0cyJGDiAimMP3l4yfMt6sqqraxb7egJ+DVAnEpJ/lynRh5v5TsfU0dIBv15RpgGiOlArGfb1Tx05SCpgCjEwYJya4l6+j2+KW3ti2QH1lSgHTNCEPoBuhGOQAIoI5e/eY49c6/3fM+fs4aHkAgYlde8RsbuVK9MYTFJrB5xEfg89lGiCaI6WCcV/v+KZNRgoY58HnQWNsyWIxwd1/EN0Wt/TGtoVSwBQmVAJx4zAWOYCIYM7fD9mXLzf69VeM3yuDUjqM1PnLwlmZOgm98QSFie07jPQTNb5dU6YBojlSKhj39aYUMIWJ0Ra91hvbloYUMI/RbZGNbrVFcgARwRy9dRD31+h37zGuxbKpHJTSYTSk5uiD3niCQoxVB5kGiOZIqWDc17th1eEuul2yEWM13mu9Me2gFDDN00rIvn69Y72x/QetwBy+TYwbDfIUMIzXjO+vGSlhtmPbaQeldBiUmsN9QoF0v+OOZBkgipE+b+7r7VbcURCJEY/rtd6YdmTDRgqYPt3Qn4mMtEoyzpnlWG9s/0ErVFRUjCmF2HbaQakdBtSr5Uv6D0PoDSgIxDh5KMsAUQopFYx7ej9LUAqY5hiUXKeytG9KAdM8M7cfiOczcqhjvbH9B4LiKLXDiEyfKoJ6z1xAb0CqEyv3mCwDRCmkVDDu6Z25fd+13GNBZahfD2NCpm6uU1nad/LgYSMFzEL0ZyIjc8nnYkLWtZ1jvbH9B63RokWL36yoqPjTysrKv2Zf/8Yktl12UGqHEa+pEcf6d+xEb0Cq06o+4HN5PVkGiFJIqWDc0zt1zL3qA0FlZKL6qWBkad+UAqY4Q726iAlHJO1Ib2z/QVsYeQBzUAeYff0VfGX8JWMY2zY7KLXDsBJ7LlmM3nhUJ6RG4APyrOm+XleWAaIUUioY9/RObKYUMMVo1eXe709dbi/1xm7f0VkzxOr9SUoBU4jhcaPEhOPaLUd6Y/sP2oI5eteZ49cbvocE0MbXEYwDcS2zh1I7DIrrcI8wM+YDMpsp+3ldWQaIUkipYNzTOzZ/rnBujh5Ht0lWws4Gb5M1q9Ftcao3dvumFDDFGV24QLTJQ0cc6Y3tP2iL/DyApgPI8Bvs9yk8q+yj1A4jG07RyS6XCLExvPEfPOzrdWUZIEohpYJxT+/wGJECBuqQYtskK1NnzosJx/Sp6LY41RuzffMUMF3aUgqYIkxs2SomHOvWOdIb23/QFszpi33rW9/6V8b3DysqKv79t7/97T9g33+GbZsdlNph8IbdtZ1IJZF8jt6AVGa4eoxY/r9609fryjBAlEqRCuYjSgXjgt6hnpQCphgzD9RPBSND+6YUMKUxdeK0CAOaPcOR3tj+g7aoqqqayZy9943vBzC+YMwwLse2zQ7sdBhwbJ2vJNx+iN6AVCZ0jjwAmHWWfl5XhgHCDusG96NUMA71/vynPzFSwHREt0dm5jKfsMnG+/W1HT9WNhWMDO0bJrUiVGgM+vOQmZm7j8RzGjHYkd7Y/gPBAHP8/qJVq1Z/96XXy8NJDTsdBhSS58G9x0+hNyBVmUu94M8Qtkn8HmhkGCDskFLBONf7Z5EwpYApkXX9e4oJR20M3ZZy9cZu35QCpjS6MQ6QA0hwDDsdBpwi5HELmzahNyBV6cbMr1zKMEDYIaWCca73D69cpBQwJTIyqVqEZly6hm5LuXpjt+/42rWizW7dhv48ZKfTnSByAH1GZWXlJcaLxYhtpx3Y6TCSRymfmFOmTp5xHPtRLmUYIOyQUsE41/vlHuN060ZKAVOMsWVGKph9aqaCkaF9Q79GKWBKoxULfqW8WHByAH1GVVVVm1KIbacd2OkwMreoooBTwszY6emvcinDAGGHlArGud7ZZcaJczZ5w7ZHdiZ27hITjtWr0G0pV2/s9g07GzxO/O4j9OchO61sEAcOla03tv9AUBx2OoycWVO0G9UULZfRRc7zP5VLGQYIO6RUMM71TkwYTSlgSmTq7AUjFcwUdFvK1RuzfVMKGHu08sGuqSlbb2z/gaA47HYYbpSw0Znh8aMdZ4Avl9gDhF1SKhjneod7dRYpYOI5dHtkZ+ZhSEw4hvRHt6VcvTHbN+WKtcfU6XNiwjFzWtl6Y/sPBMVht8PAdGCCwFBvPAcae4Aoh5QKxgETOTEg96AUMKXwlVQwbPKBbY9dYrfv9NVblALGBp3mniQHkOAYdjuM2CKcKhZBICTQ5kf/u7ZDuT72AFEOKRVM+czcuicG5DEUs1sq6wb0EhOOp1F0W+wSu31bKWAWUQqYUuh0wkEOICIqKirewrbBDdjtMBrq2K5Fb0CqMXPnoRiQRw5BuT72AFEOKRVM+UwdM07tz6dT+6UyMtlIBXPxKrotdondvuFgG6WAsUcnEw5yABFRWVn5c8a9jP/Efvx1L6/FnM0h7Dr/yFjNvv+G09flw26HYcYtRGdNR288qtEq/zNnJsr1sQeIckipYBw8u00ib2eC8naWTPic8R2OvfvRbbFL7PbdkALmDPqzUIWRKROMCceVsvR2z8sg2EKLFi1+nzlaA6uqqu4YZeAWtmzZ8jtuX4c5ct81y8uxr19n19zh5HWNYbfDyNw34haGDURvPKrRjQLgTog9QJRDSgVTPmHljw/IxygFTKm0UsGsUi8VDHb7phQw9hlbsVxM0vbsLUtv9zwNQtlgztefMqdrFmOaOV4PYSXOrS1i9p7D2Xt1NH9m759w8rrGsNth5NLq18zEYkMKn8UQEwAAIABJREFUmKMo18ceIMohpYIpnxD7xwfkW5QCplSmzorKKRB7im2LXWK2bysFDJw4T71AfxaqEBw/PuFgjmA5ejv3MAiO8c477/zvzAGbyZhhvA6rb4yfMYesu9P3Zu8zj/H9vJ/jb7311lfLfV1jQIfx4oX4MJVKM24hF4rZ+n+6M2KcoM5cv4VyfdC5HL0x+SzXkArmWfZTdHtUIpz+hc/b82QO3RZVmH3UkAoG2xa7xGzfuWhDChjs56ASrR2OKRPK0tupf0EoE8zp+xpz8PrDFjBztrLgALZs2fKPzb+z3/1bxh84vQ5sLbPrvJv3c/rtt9/+rXJf1xj1ZSA1cwr/0P7k4f1y/ru2iPQTtR9/9aMfYpuiFGLDB/Dn9otcFtsUZfCrn/xEHDjq1RnbFKXwxa9+VV/b/oP6UMeP6r/4/HNsc5TBT2ufiN2NKeOxTVEKv3z5QsSFD+5T1v936l8QygRz7n7GnKzdrVq1+nv246819Rr29xVOr2Ns7bbP+znl5HWNAR8iuzPGuBG3kNy7D30GpQqfpUQKmBBPAfMZig0qrgACzVQw6fMX0W1RhWYKGKgEopre2LR2OGqj6LbYIWb7Th0+IrYyFy9Efw4qke9wdPyYh1U9y35iW2+n/gWhTMAKoB/XYY7cn8PqHnzfsmXLSjh5DN8zZ69VKa8rBugw+AfRTtzCbiNuYeUK9BgKVQiB0ZgpYMyYkXL0xialgrHP5NHjIr3E8kXK6Y1NVVPBYLZvSgFTPiERNA8NevDUtt5u+xsECcGcvUnMuXuPcUqrVq0q2K/eYA5eiP3+d4q8rijK6TDSF8y4hYnojUcVWilgZuOkgDE7DBUdQEoFY5/xjSIFzMs9O5XTG5uqpoLBbN/Qr1EKmDKf3cxp4tmdPmdbb08cDoI+KKfDoJOZ9gkzY8wUMGaHoaIDSKlg7DM6T6SA+eGVi8rpjU1YaVYxFQxm+6YUMOUzvnaNWD3dtt223tj+A0FxlNNhQNka82QmlLPBbkAqsCEFzBE0G1R1ACFLPp9wDOiFbosqDI8WKWB+Hg0rpzc2VU0Fg9W+eQqYru0oBUyZtEroLbZXQo8cQIJjlNthQJoEEbdQi96AVGDYSAGTvnYLzQZVHcBXJxyfotujAkPdRQqYz3/6U+X0xmbmYUMqGGxb7BCrfWcjRgqY3l3Rn4GKTF+9JeLD2RhhV29s/0FrVFRUdKiqqjrBeBd+rqys/Mv8VCwqoNwOIzJjqohbOHMevQGpQOgceVA+6yyxbFDVAQTWDe4nJhxscMa2RXbmYlkxIPfspKzeqM+PTTJgsgGTDph8YNtTKrHad7kODFEwG0kbDnQX23pj+w/agjl6Y5jDd4N9/cjM9wcHL+B32LbZQbkdRnxNTVlxCzoStkXgWcE2CWb1FJUdQDMVDGzPYdsiO9M37ooBeewIZfXGppkKBsIPsG0plVjt29rCXGRvC5PYwFC39mILPfHMlt7Y/oO2YI5eDOoBG99/avz6jbzvlUC5HUbywCEjbmEReuORnVYKmBGDUe1Q2QGEgHw+4di5C90W2WmmgInNn6us3thUMRUMVvuOr11LKWAcMjxqmFG28b4tvbH9B20B1T/Yl1+H76uqqj6Br1B5o9QEzLKg3A4jfeWGcGqqx6I3HtkJqRGwU8CYHYaqDkFy337h1Cxbim6L7IxvEClgEps3Kas3NlVMBYPVvqOzZhgpYM6iPwNVaZ7aTx47YUtvbP9BWzBHbzNzAscb33MHkP08sqKiYg2uZfZQboeRrUtatR+xG4/slCEFjNlhqOoQwEqMSAVTjW6L7IzOnS0G5OMnldUbmyqmgsFq33XDB4nVq3uP0Z+Bqoxv2iTGiI0bbemN7T9oC6gEwhy+K7Dix/hLxjD83KpVq3+DbZsdlNth8KP/ndvU17Z9rz6XeonegGQmxMbw2d3Bw6h2qOwAUiqY0mmmgMncvq+s3thUMRUMRvumccAdpo6dFLtEbPJmR29s/0F3vAEl2CoqKr7HnL//xH7+MrZBduGkw7BmfpT8s1laKWCu4qWAMTsMVR0CngrGqJlJuSebZ6h7B/55e5Z4pqze2FQxFQxG+6adIHeYuf1AhFSNGmpLb2z/gaA4nHQYDbEfVP6nOULnyE8UhvFSwJgdhsoOAeWeLM6GFDCdldcb9TkqmAoGQ+/0lZsUC+4Cc8nntjNFkAOIiIqKin9XWVl5hPEZ408N/gy+YttmB046DDr9VULDNlPAdGmLmgLG7DBUdggi06cYuScvoNsiK/NTwKiuNzZVSwWDoTdlg3CPdnPFkgOIiKqqqjvM2ZvLHMHvsu//JJ/YttmBkw7DzP8EZc6wG4+slCUFjNlhqOwQxFZTKphiTB45JtrkgnnK641N1VLBYOgdX1NeHVvi6wxXjzFChW6WrDe2/6AtmPP3GfvyBrYdTuGkw6AM8MXZkAJmBrotqjsEyX0HjFQwS9BtkZXxDRvEacLNm5XXG5uqpYLB0Ds6c5pYlT99Dv3+VSesovLP24FDJeuN7T9oC0j3wpzAv8a2wymcdBgNNSDtlbDRiVYKmLVr0W1R3SFIX7omTmZOHI9ui6y0UsAcO6m83thULRUMht51wwaKuNz7T9DvX3Umtu8QY8WampL1xvYftEWLFi1+r6qq6jHjQeYIrsontm124KTD4CkAurYTJWySz9EbkIyUJQWM2WGo7BBka+PiZGa/nui2yMr8igKq641N1VLB+K037/87tRYpYNJ0Mt8pU2fOi8/bjKkl643tP2gL5uhtZ87fE4gDZF8n5xPbNjtw2mGERw4xco49RG9AMtJuXIeXVN0h4AMOpIKhAacgQ906WDVFVdcbm1YqmMH90G0phX7rnQ2JCVmoXw/0ew8CIbuBndRD5AAigjl6P/7Wt771r7DtcAqnHUZ0zkyj6sAp9AYkI2VJAWN2GKo7BHVDBxipYJ6i2yIbc9GMlQImKHqjPk/FUsH4rXf68nWxYjVhHPq9B4GQ39TO540cQERUVlbeaNGixe9j2+EUTjuM+Pr1RtD5FvQGJBtlSgFjdhiqOwSwPSJSwZxHt0U2pm/cMVLAjAyM3thUKRWM33on9xuHspYsRr/3oLBuYG/xeXsSKUlvbP9BWzAHcGBVVdU1xtYVFRV/k09s2+zAaYeRPHzUSjuB3Xhko0wpYMwOQ3WHIF5TI9JO7NiJbotszE8BExS9salSKhi/9aa26D4jUyaKz9v5yyXpje0/aAvm+EUKMIxtmx047TDS119ddSA2MHXyrBiQZ+GngDE7DNUdAlp1KMz8FDBB0RubKqWC8VtvWo13n7GVK4RTvXtPSXpj+w8ExeG0w2gcd0RsoEwpYMwOQ3WHwIo7mkhxR41ppYAx4nGDoDc2VUoF47feFI/rPhN79onPG5t4lKI3tv+gPb797W+/07Jly//cggHblnLgRodhnTyMP0NvQDIxtlieFDBmh6G6Q0AnDwsTCsmLE/kPAqM3NlVKBeOn3taJ/Hbv88ML2PceFEKoAf+8Ta4uSW9s/0FbMMfvD6qqqs4x/oIxY3w9/81vfvNtbNvswI0OIz/3GHYDkokypYAxOwzVHQLKPVaY+SlggqI3NlVKBeOn3tnamHgu/SknJ9ZzJQcQEZWVlTsZF7311ltfhZ/hK3MAFzLuxrbNDtzoMMytp+SxE+gNSCY2pIBJottidhhBcAisrSeqPmDRCsXo1RCKERS9UZ+rQqlg/NTbqsozqfhKFbF02sl1Sg4gIpij97yiouJf5P+uRYsWv8l+/wLLpnLgRocR37BRxLpt2oTegGRhLvWSN2JZUsCYHUYQHIII1R99jdZhrHGjAqc3NlVJBeOn3sl9+6kut0dsKK/XfGwlOYCIqKysrGvZsmVl/u/gZ91OAfPO4Ohxcdp13hz0xiMLM/cei6X84YPQbcnvMILgEECtTH5SbvsOdFtkYeMUMEHSG5uqpILxU284FMPb4M5d6PcdNEZnTS9pgksOICKYAzgYnD32tVdFRcX/C1/BKWTfD8G2zQ7c6DAyN++J1YfRw9EbjyyULQWM2WEEwSFIHjhEqWAasamE7EHRG5uqpILxU284FMOdlLMX0O87aISsEdy53ra9qN7Y/oPWYA5fW8ZjjA+Nr23Zr9/AtssO3OgwcvGciD/q3hG98chCaLwiBcwadFvyO4wgOAQNJajGotsiC6NzZr1WkjEoemNTlVQwfuoN9Wr5NuXDEPp9B43JQ0fE523RwqJ6Y/sPBMXhVocR6tFRnECMZdEbkAyULQWM2WEEwSHIhhJiwtG3O7otsrBxCpgg6Y1NVVLB+KU3HIaBQzFwOAYOyWDfd9CYvn5b7KiNH11Ub2z/QVtUVFS826JFiz+C71u2bFlVWVl5pqqq6iR8j22bHbjVYYTHjBBxMjfuojcgGRiuHiuexxU5UsCYHUYQHAJ+Uq6zmQrmJbo9MjDUrb2YgCWfB05vbKqSCsYvveEwDH8eA3qh33MQmbVO9Hcpqje2/6AtmMMXeuedd75mfL+PcS5zCicyJ/A4tm124FaHEZ0/V6x4HTmG3oBkoGwpYMwOIygOARyu4Ste9ygVTKEBI0h6Y1KVVDB+6Z2+eMVIVjwB/Z6DylD3V3N6FtIb23/QFszR+yF8hdQvzPn7DL6yH7/Cfv8Jsmm24FaHASlgeMzbhg3ojQebVgqYzm2kSQFjdhhBcQiiZiqYU2fRbcFmUylggqY3NlVIBeOX3nbKlRHLIxyoLFZcgRxARDCnL96qVasK5vD9A/v+NPwO8gKCM4hsmi241WGkjp0Up17nzkZvPNiUMQWM2WEExSGIr1lT0kk5HZg8fFS0vYXzA6s3NlVIBeOX3rGVK0Xb27Ub/Z6DSkipxnfUjhYurkAOICKYozeQ8SdA5vj9f/C7li1b/t/s58vYttmBWx0GzFT4KsSooeiNB5uwKiVSwExHt6VxhxEUh8BKBbN4Ebot2DRTwCS2bHnl90HSG5sqpILxS+/I1Eli9f3cRfR7DiobdtQ2Nqs3tv+gNeDAB0PL/J8Z/xjTJrtwq8OAWAUeh9StPXrjwaaMKWDMDiMoDgEcruETjmpKBdNUCpig6Y3NhlQwK9FtKUS/9K4b1Fdshz+qQ7/noBLacrEdNXIACY7hZocBdUh5xxDNoDcgTMKqFF8tOHAI3ZbGHUZQHAI4XMMnHH26oduCzfBIMwXMw8DqjU0VUsH4oTdPAdP+Q0ZKAeMloS3zCe7Iwjtq5AASHMPNDgOC0HmczPXb6A0IkzKmgDE7jKA4BCIVTBuRCialdyqYUNd2r6WACZre2FQhFYwfemefRMRzGNgH/X6DTGjL8JxrWdsudJCQHECCY7jZYUAQOl/5OnQUvQFhEhIU85XQOnlSwJgdRpAcgoZUMI/RbcFicznDgqY3JlVIBeOH3unzl8VK6JSJ6PcbdDakEksV1BvbfyAoDjc7DAhC57Fv69ahNx4sypoCxuwwguQQQJ1lHvt2Ut9UMFbVgEYpYIKoNzZlTwXjh96J3XtFLOSK5ej3G3QW20kiB5DgGG52GKkTp0Xg6uyZ6I0Hi5CYWMYUMGaHESSHwCqavnUbui1YhNV2kQJmQeD1xqbsqWD80BscP97mmCOIfb9BZ2zJ4mZjyckBJDiGmx1G5o4RuDpiMHrjwaKsKWDMDiNIDgHUWS6laHqQWSgFTBD1xqbsqWD80Bu2fvmq+/nL6PcbdCZ27BQ7ajU1BfXG9h8IisPNDsMKXO3SVrrtT98arZkCZo1cKWDMDiNIDkH66s2SiqYHmdE5M8WAfOJ04PXGpuypYPzQGw5/8G3wx2H0+w06U2cuiHjL6VML6o3tPxAUh9sdRqh312YDV4NOWVPAmB1GkBwC+IzpngomPHKIOAhz5+Frfwua3tiUPRWM13rzgzDtP+BpYGQ9CBMkWifPh/QvqDe2/0BQHG53GLAaw+NkrsqVAsUvNgTu3kC3pakOI0gOAU8F06WtSIGSeoFuDwYLpYAJot7YlD0VjNd6Q+Jnfv+D+qLfqw5sOHnetMNNDiDBMdzuMCAei6+AHTyM3oAwaK2ARuRbAQ2iQwDxpnwF7O4jdFv8ZjaSFiugvV9PARNUvTEpeyoYr/WG0m98BXTqJPR71YXWlvuTSJN6Y/sPBMXhdocBJzJlLIPmB3NxsxxeB3RbmmIQHYLo7BkFY+CCzvS1W83GQAZRb2zKnArGa70Tu/aIGMiVcsZABpFW3eUmDt2QA0hwDLc7DMjJJuspWK+ZuXlPDMhjRqDb0hSD6BBAzkldU8E0lwImqHpjMzJ5ggjxuHAF3Ra/9TZPQSf27EO/V10IzjZ/5sz5bkpvbP+BoDjc7jCgKoOsefC8ZvKwOSDPR7elKQbRIUgeOiKe+aKmnaAg03J+t2zVRm9sxlauKDggY9NrvS3n96J8zm9QCSmH+Korc76b0hvbfyAoDrc7jIZKGK21SwUje2LiIDoE6avNb4MGmZBwvbnt7yDqjc3kPmNAXrYE3Ra/9ba2v5uIRyN6w/SlayLuclJ1k3pj+w8ExeFFh2HVwg0l0BuQn4zMnCYG5NPn0G1pikF0COCwTXMHIYJMqxZygQMwQdQbm+nL18WAPGEsui1+6i37AZigMlsbFztq/Xo2qTe2/0BQHF50GNA58q0C1lliNyA/Cfma+ID8oBbdlqYYRIeAp4JpJhVKUAmDcG3Hj/lqey79Uhu9sSnzhMNLvWVPgRNU8v6tU+sm2zk5gATH8KLDsGoY7j+I3oB8a6gwILf/kCdKhdkytj1NMagOgZUM+fbryZCDStiG4wPygF7a6Y1NOOXPJxzxZ+i2+KV36uwFqZNgB5nWSv+9J6/pje0/EBSHFx1GYvuOZmsYBpENM2R5k6QG1SGIzpkltt6PnUS3xS+mzl0qmpMtqHpjE0758x2OG3fRbfFL78TOXUYZvFXo96kbo7OMVFcnz76mN7b/QFAcXnQYEAPHB6cZTdcwDCJTZ843W7dRBgbVIYhv2iQmHBs2oNviF81C8bHVhQfkoOqNTUi7w3c4Dh1Ft8UvvWPLlop73rcf/T51Y6FUV+QAEhzDiw4jc/+pWA0bOgC98fjFxLbtwglZI28C7KA6BHAKlqeCmT0D3Ra/GFu8sGjN6aDqjU1Z27qXekcmjhernpeuod+nbiyU75McQIJjeNFh5NKfiFQwHT/WJhVMw6rAEXRbCjGoDgHExug24QiPGyUG5Gu3tNMbm7Ku9nupd6hPNy0zO8jA9PU7ItUVa/ON9cb2HwiKw6sOA46t8w6jNobegPxgeKwZF3QH3ZZCDKpDkMt8ol2KilCPjuIgQiyrnd7YlDXe1yu9cwlR4hJO2+syoZeJuWhGnDzv2fk1vbH9B4Li8GzLYFK1VlnjQ93Nk4E5dFsKMcgOQd0go2j6ozp0W7xmtsCAoJPemOQn/jvId+LfK72tEpejh6Pfo64Mde/42vhCDiDBMTwLGl6xXNqSSW7Tyg3WS77cYPkMskMQmT5FnJQ7cx7dFq+ZvnqzpOonQdYbmw05P5+i2+K13la5RUlLXOpA8+Q5OOP5emP7DwTF4dUAkdx3QJxSXCpfySS3mb5iDMjVY9BtaY5BdgggIF/mMnxuEvJr8ra1ZLG2emMzalb9OXUW3Rav9Y6vqRFta9t29HvUldEF80SM+dHjr+iN7T8QFIdXA4TlFGlQo7XUARmbQXYIrJNyrKPEtsVrxlatFAPyzl3a6o1NKzXHlq3otnitNyR/FqvrF9DvUVfGN295LdUVOYAEx/BqgLDilHp0Qm88XhOSo5YyIGMzyA6BTnFKkSkTxIB8/rK2emMzeeSYdBMOr/SuG9hbxNc+DqPfo660Ul3NmfWK3tj+A0FxeDlAQJA67ziYM4jdgLwkVGMoZUDGZpAdAqgDrMtJxbr+xgn7p1Ft9cZm5tZ9MeEYNQzdFi/15im92r0vUnppcsJeRmbuPhKft5FDXtEb238gKA4vBwiIieMnga/cRG9AXhLqsZYyIGMz6A6BDrnKcqmXIsdm59ZFHd2g642qg4QTDi/0Nh0PqEeLfX86M5d6Idp9l7bW540cQIJjeDlAwAGQoJcPyqVfihlyp9bSz5CD7hBY1QouXkW3xStm7jwUKwEjBmuvNzZDfbuLCUddEt0Wr/ROHT/12tYjEYfWBDectPTG9h8IisPLASKxe484HLFiOXrj8YqZe4+VmSEH3SGwUg/tDm7qoeSxE2JAnjtbe72xKVt5NC/0hkMH/PDBpk3o96c7IxPGGjtqNyy9sf0HguLwcoCAjpGXTGIdJXbj8YoNwbkz0W0pxqA7BMm9+8WEY1lwUw/F168veUAOut7YjC1fJiYce/ai2+KV3lBfm8c3s34O+/50J2SZ4Dtq+w9aemP7DwTF4eUAAVsj/CRwn27ojccrwkAsjudvRLelGIPuEKQvXzfyMY5Ft8Ur2hmQg643NsHx4xMO5ghi2+KV3lBfmycgvv8E/f50Z2LHTjHW1Ky29Mb2HwiKw8sBAoJVQ93aGyVsnqE3IC8IW3F8QD52Et2WYgy6Q2BVZOktd0UWJ7QzIAddb2zKtsPhtt5Wybt2H/B629j3pztTZy+Iz9v0KZbe2P4DQXF4PUCEx4oSNukbd9AbkCf3N3KIGJDvPES3pRh1cAhUqMlcLsWA/FHJA7IOemNSth0Ot/XOPAyJ+OZBfdHvjZinx+B+lt7Y/gNBcXg9QMQWLRRxCwcPozcgtwkrnLWd2/Dj+XBMH9ueYtTBIQiPHSkmHNeDN+HIPq4zBuQ+pLcE5O2/azsx4Ug+R7fHbb1Tp8+JFacZU9Hvjcg+b5lP62vbf8BXZWEySA4gwTG8HiDMuIXY6lXoDchtZmvjYgWgXw90W0qhDg5BkCccUIqLD8jTJpPekhASQfMdgFv30W1xW28oc8djztauRb83oiBM/syqLOQAEhzD6wEide6SGLSmTERvPG4zffGKuLfJ1ei2lEIdHILE9h2vBEoHiYlt28W9rakhvSUhlILjE44jx9BtcVvv6Py50twbUdCqOsXGVXIACY7h9QAB1TH4tlX/nuiNx22qludQB4cgdfaicMpZR4lti9uMLlwgBuRDR0hvSWitkq1bh26L23qHRw2VZnWTKBhbtVKkHtq1mxxAgnN4PUCoFidnqzEuWyoG5L1qVDrRwSHIPomICceAXui2uE27B6p00BubqVNnRR7QmdPQbXFT7yD32yoTqmqJXKdLyQEkOIcfA0R4ZDBnkpEJ48SAfPk6ui2lUAeHgJ+U7fixGLjSL9HtcZOhbuYJ59JSKumgNzYzD2rFhGNIf3Rb3NQ7WxtTKr5ZF+anHiIHkOAYfgwQQY0laVybUXbq4hBAWT4+4bj7CN0Wt5gNmzkOu5LeErHxyUxMW9zUO33+shG7PQH9GRMbmA01HDwkB5DgGH4MEEE8TZZLPBMNsWs7vl2CbU8p1MUhgML1qiTnLpVmlROoB0p6y8W6wX3FhONhCNUON/VO7NwlthpXrUR/vsQGiq351nyH41nmJTmABGfwY4Cw8klND04+qczNe6Ls2Ojh6LaUSl0cgobyfBvQbXGLDXWOl5LekhH6NT7hOHMe1Q439Y4tXvRK3VmiPDR3OLL3HpMDGHRUVFQMqays/EfGavb9N5p7bVVV1Z+wL1956623vtqqVauKUt7fjwEi+8hMYBucjPKwnc2DvxfMQ7elVOriEECdXK7N7BnotrhFOGnOT//t3kN6S8b42jVCm23bUe1wU+/wuFEivvnqLfTnS3yVVj3wU2fIAQwymMP3XebULYfv2devMydwR3OvZ3+/xV73gnHX22+//WYp1/BjgLAC86GEVToYNSUh7QPv9LdsRbelVOriEGTuPRETjqED0G1xi5FJ1WJAvniV9JaMyUNHxYRj4QJUO9zUO9SjozhwFMuiP1/iq7TGnq1byQEMMpgjN5w5gR3Nn5mDlyjy+tZ2r+HXAFE3bKCIk7n3GL0BucHorOnGLOwsui2lUheHAOrkwmQD6uZiB+a7xVDf7mLbJ5QgvSVj+sZdEQ4yZgSqHW7pnY2kRXxzr87oz5b4OpOHxYQjtnA+OYBBBnP45jG+n/dzHLZ3C72eOYBTWrVq9Xfs67AWLVr8USnXgA7jxQvReXjJ6JyZwmE6fsrza/lBWF3iA/LDp+i2lErQ2S+9sdlQMqkO3RanfJZ6zu+ltktbNgB8RnpLxmfmgbBuHVDtcEvvzNUbIma7egz6syU2oc+NO0KfcSPJAQwymCO3sKKi4t28n9Nvv/32bzXzX96Af958883fZs7ipVKuUe8TXu4RNYFf7t7u1yU9wxeff14f6vgRT//wxS9/iW0OoQmk54k4mR/fuoFtimP8PBoWh1rGj8Q2hVAAkX4iJdSvfvgZtimO8YNTx/m9PFu7CtsUQhP41Y9/LFace3UmB1B1MKfuL8BZY7zYiDtgJY85gO3zXpsq9D6tWrX6e/b3mcaPX2b//yelXB8+UH6sEKRONgTmY8+gnBJWlcxDLdi22KFOK0INgfnb0G1xytRRceAoNn8u6S0pIT0PD3G5egPNBrf0jhsHjpK796A/V2LTNGM0r3/ve7/r0AUhyArm0P05rALC9y1btmQ+XeVe82/MMWyV/1rmAP4Ve8134Pt33nnnD9lrj5ZyDegw4APlddxC5n5wAvNTZy8YaW2moNtih6CzX3pj0wrMV+iUdiGWe+BIJ72xGVu2RDhN+/DKQrqlN1SZsHvgiOgvzbKQjz/+p//ops9BkAzM0ZvEnMD3jPg+M7XLG8zBC7G//U6j13aEFUP2t/EynQIG8sB8STLmO2Vi+w6xJbemBt0WO9TJIVAxT2MhRmZOE/Gzp8+R3pIS0vPwVdqVK9BscEtvq8JRnRoVjnQkTGxBo6etv/eB604HQR/4OUDIkjHfKWOLForZ/sHD6LbYoU4OQS75XLlKLYUIdWZ5u3nEK1T6AAAgAElEQVRQS3pLyvTFK2JXYDJe6TQ39FaxwpGOTGzZwnV60vrdsdg+BEFh+DlAWCsZCqVOaYpWktTrd9BtsUPdHIIgrGSIWrMfcsL3pLeczNaKGq11/Xqi2eCG3lZKmwCsnAeZZrL7p63f3YjtQxAUhp8DREMs0xb0BuSEqiZJ1c0hsGKZLl1Dt6Vcwmo5dywG9yO9Jaao0dqG12jNpV6g2OCG3slDR6RIak1snpm7j0RqqDbvXsf2IQgKw88BInn0hOhc5s1Bb0DlMhvNKJskVTeHoKF82l50W8qlVUd75jTSW3KGRw4VW/W3H6Jc3w294zU1UpS1IzbPXOoln2w8bfPuM2wfgqAw/BwgoGPk2wsjBqM3oHIJtTH5PYwfjW6LXermECT37heB+cuWottSLuHkLz9wtG4d6S05YWLLY4OPnUC5vht6R6ZNFmE6Zy+gP09i80zu3Fn/pPX3+mP7EASF4ecAYc5aaju1VvYkcPLAIeFULF6Ebotd6uYQpC9fF6tnE8ai21IuzdN+ySPHSG/JGd+8WTjr69ejXN8NvesG9hZxs08i6M+TWFxvbP+BoDj8HiDqBvRSuoOxthV37kK3pZwOQyeHIBtJie363l3QbSmX4VHDxLbirfukt+Q0A/Mh2T3G9Z3qnUsbE/SOHys7QdeJ5AASHMPvASIydZKxxXARvQGVQ9j65QcLrtxAt6WcDkM3hwDqs/IDO/Ecui12yQ8WdG0n7E8+J70lp5XsfthAlOs71ds8WFA3fBD6sySWpje2/0BQHH4PECoHGfMBuUtbcdIv/gzdnnI6DN0cAjNjvmope4DZUEKsYPbtTnorQJ7svh0ku/8IZQXNqd6pYyfFCubc2ejPklia3tj+A0Fx+D1AqJxmIPvIqAE8sDe6LeV2GLo5BNFFC5RM2g2EUlw8hnFSNemtCK2k3fef+n5tp3rHN2wQMYybNqE/R2JpemP7DwTF4fcAoXKJrtTxU8J5nYUT4+NGh6GbQ2CV7atZjW6Lbdt37xUHjlYsJ70VYXTOTBHicuyk79d2qjf0a9z2E6fRnyOxNL2x/QeC4vB7gDBLdNUqWGoovmaNkch6K7ot5XYYujkEEGvKV9GmTkK3xS5jSxaL1ct9B0hvRWil7Vm7xvdrO9W7bugAY/XyCfpzJJamN7b/QFAcGAMExDTxk8ChBHojssPI5GoxQz5/Gd2WcjsM3RwCOG3Ot+0H9EK3xS5hlZzHL94oL35RR72xmTpnTDimTPT92k70hpjF2g5QcvADHsuI/RyJpemN7T8QFAfGAGE6UlBAHbsR2WGoZ2fhuEZS6LaU22Ho5hDwga1za9QSXWXb3cmZ3TrqjU3r4E6fbr5f24neDSUH+6I/Q2LpemP7DwTFgTFAxFauEFupu3ajN6JSmQ3F0Tp2NzsMHR0CpytpGLQG5EHlD8i66o1JCGsJdTdqhUczvl7bid5WycEZU9GfIbF0vbH9B4LiwBggkvsPiOD2JYvRG1GpTJ25oGwsWX6HoaND0BBLtx/dllJpHThykFRYV72xCZVn+ITj0jVfr+tE78SWLUbs4lr050csXW9s/4GgODAGCBXr6cY3bkQt8+RWh6GjQwCOn2oTDhiIxYGjLaS3YoytXIlSLciJ3jDR4PHNbOKB/fyIpeuN7T8QFAfGAJGLZcV2aveO6I2oVEamTxUd5Kmz6LY46TB0dAhg61e11ENuVMzRVW9sQs5Jket0vq/XdaJ33cA+4gTwwxD68yOWrje2/0BQHFgDRKh3V+MkcBy9IZVkr3ly+WkU3RYnHYaODgEcouA1Tju1VqbGKcSaOm0fuuqNzcztB2LCMWKwr9ctV+9c4ploH53bKNM+iOQAElwA1gBhrXCcuYDekIoRgrnFimUH5XIXNu4wdHUI4HQjX+F4UItuSzFmzc9bj46OPm86643JXDqvJFzmU9+uW67eVkjO2JHoz45oT29s/4GgOLAGCIilU6XskFWSa8I4dFucdhi6OgSYFRrs0q3Pm856Y7OhJJx/SZXL1Tuxe4+IkV2+DP25Ee3pje0/EBQH1gCROnlWDHLT5U87kNi2XdlyYo07DF0dgsTWbULDNf5XaLBt646dYkBetZL0VpTRubPFyfOjJ3y7Zrl6Q112buuBQ+jPjWhPb2z/gaA4sAYIiKXj21z9eqA3pGKMzpnle2fuVYehq0MA1Vv4hGPyBHRbijE6f674vB0+SnoryoYJR41v1yxXb4hV5KuVt+6jPzeiPb2x/QeC4sAaIHjC1G4dUBKm2iUk4xXxY0/RbXHaYejqEGTDSTHh6NUF3ZZirBs2UHze7j4ivRVl6twloyScfxOOcvSGsm+17Y0ScGkqAacSyQEkOAbmAAExTqIk3FX0xlSIueRz44ScOidIm+swdHYIwPnjJ2uZM4htSyE2DMgfOq7JqrvemMzWGROO3l19u2Y5emfuPBQVZ4YPQn9mRPt6Y/sPBMWBOUDEVq8SCVO3bUdvTIXYcEJuBLotbnQYOjsEsP3LD4Kcv4xuSyG6OSDrrjc2Qz06iQmHTzsc5eht5SxcMA/9eRHt643tPxAUB+YAATF1vPOZMwu9MRVikE7I6e4QwAEQPuHYug3dlkJMHjri2oCsu97YtHY4fCoJV47esRXLUaqWEN3RG9t/ICgOzAECYuqcFrz3mkE6Iae7QwApYMSEYya6LYVolRHbsZP0VpxwitstLb3SOzxulHBSr9xAf15E+3pj+w8ExYE5QEBMHcTWQYwdxNphN6imCFtxPCD/9kN0W9zoMHR2CCAJNJ9wDJZ3whGZMNa1VSPd9cZm8tBRX7dX7eoNB/Fqu7QVB/Hiz9CfF9G+3tj+A0FxYA8QEFvHB7yrt9AbVGPyjP4QkN/BeUC+DNTdIeATjk7GhCP1At2e1+yDk/Hd3TsZr7ve2IRJo58HLOzqnX1cJ+wb0Av9WRHL0xvbfyAoDuwBIrZsqdgm2b0HvUE1JuTFwqjp6WWHga03NsOjh4sJx4076LY0ZrY2Lk6O9ulGegeA/ER3h49EipXUS8+vZ1fv1InTYoVy5jT0Z0UsT29s/4GgOLAHCIit453QwvnoDaqgbYsWoNviVoeBrTc2Y0sWi5jOffvRbWnM1NkLInfc1Emkd0BoTTiueb/DYVfv+Nq1Iln15s3oz4lYnt7Y/gNBcWAPEJnbD6TNQ9WwOrkX3Ra3OgxsvbEJjh8/1c0cQWxbGtOqj82+kt7BoJ+nbO3qHZkyUaRFYhMP7OdELE9vbP+BoDiwBwiZM9GHxxjxiddvo9viVoeBrTc2YeuXb+uPHo5uS2NGJlcbA/JF0jsgTB497luqK7t6h3obidFDCfTnRCxPb2z/gaA4ZBggZKxF+cqBAUlPKJfTYcigN6quqRd8sgGxWTId7BGlEdu7mjiY9MZn9pF/By3s6J0Np0S8ac/O6M+IWL7e2P4DQXHIMEBAjB2Py9p/EL1Rmczcfyp9ypByOgwZ9MZmeOQQ4yDIXXRbTFopagb2Jr0DxPya515XBLGjt1WreHI1+jMilq83tv9AUBwyDBAQY8fjspYuQW9UJq2tm7mz0W1xs8OQQW9sWrGdu3aj22LSyhnn4ueN9JaD1tb+OXe29t3QO75xo4g3XbsW/fkQy9cb238gKA4ZBgiIsZMtLiu2Sv46xeV0GDLojc3kkWPSVQSJLVtiOKXupUMiveWgdbhnw0ZPr2NH74Z4UzoAoirJASQ4hgwDxCtxWZIcBHGzIoMsJIdA0EqA268nui0mrTjYm/dI74DRSu8zZYKn1ylVb4hvDnVt51rCcSIOyQEkOIYsA0R41FDf8mUVY37cTi6WRbfHzQ5DFr3R9e3RUcRlhZP49qReenIwhfSWg9mIceCie0f+2fPqOqXqnbn3RPoa7MTS9Mb2HwiKQ5YBwsqXJcGWa/ZJRHTY/Xqg2+J2hyGL3tiEZMt8C+zUWXRboAyiFyEQpLc8hNVmPuF4HPbsGqXqDYft/KxRTPROb2z/gaA4ZBkgUsdPiW2S6VPxbTl5VtgyA98WtzsMWfTGZnzzFhGXtaYG3ZbE9h3iENTKFaR3QBmdPVNkOjh2wrNrlKo3VF0SWRcOoD8XojO9sf0HguKQZYCAZKR81a1HJ0+3SUphfN064Rxs2oT+XNzuMGTRG5sQ28lX3caPRrclOmuGJ84B6S0PEzt2euLkl6M3pLbi8ab3HqM/F6IzvbH9B4LikGmAMLdJMg9DqHZY24MBOyFHDkEDIbk3JPmGZN+5zKeotoT6dhfbg08ipHdAmb56U0w4xo7w7Bql6A2HPsCO2q7t+GEQ7OdCdKY3tv9AUBwyDRCQA42vhBw8jGpHqHfXQJZIIofgVdYNG4hegSZbl7QqMri98k16y0Oe6aDdB/W1HT/2bMJRit5QZpASQAeD5AASHEOmASKxx0gIvXghmg1BLpFEDsGrjC1eJA4esc8dlg1wCIUPyNMmk94BZ93wQWLCcfuBJ+9fit5WeIvHOQmJ3pMcQIJjyDRAZO48FOkJhvRHsyF1+pwvObuwOgyZ9MYmrDTz05Dz5qDZEF+zRgzImzeT3gGnOeFI7t3vyfuXoreV3/TCFfTnQXSuN7b/QFAcMg0QEJNS26Utj83Cyr8HQdp8VWjrNvTn4UWHIZPe2Mw8eOp6/V27DFcbA/JF9wdk0lsuJg8c8jT9SjG9ef/aubXoX+PP0J8H0bne2P4DQXHINkBEJuGWKDLjwtI37qI/Cy86DNn0xqRI+N1exHtG0v5fnw/IbTwbkElvuZi5byRgHtDLk/cvpnfmtrHDMnQA+rMguqM3tv9AUByyDRCYRcqzcEIOToZ2aRvIE3LkELzOyOQJYsJxxv8JR+buI09DHkhvucgnHL06iwnH06jvelsx1ksWoz8Lojt6Y/sPBMUh2wABW2FY+dlSJ06L+L+pk9Cfg1cdhmx6YxOC4fmEY90636+d2LnLOPS0iPTWhF5mOiimt3XtQ0fQnwPRHb2x/QeC4pBtgOD52dq9b6RLcK8uaimMLVsq4v+270B/Dl51GLLpjc30+ctoEw4r3ySbeJDeetCKA2TOmN96w9azDHlWie7pje0/EBSHjANEeMRglDg82IrDzgvndYcho96Y5BOO9h9ywve+XZdNbqz4v2iG9NaEVp3xXl18zfuYDRv5Jrt3RK+0RHRPb2z/gaA4ZBwgYsuXiZW4nbt8u6aV/69b+0DG/5kdhox6Y9M8ievnwaP0FaMyxMihpLdmtFbi7j/xTe/UsZOe5Zsk4pAcQIJjyDhAQE1Uvk0yc5pv17Q6yOlT0O/fyw5DRr2xCSl/eCwem3j4dc34+vXGYac1pLdmhET3fIK7e49vekPqGZH0fB/6/RPd0xvbfyAoDhkHCKs8FtSr9KlOK5yM83vVEaPDkFFvbEJlBn4ad1Bf364ZHjNChDlcukZ6a0ZzghuZPtUXvV85ffw4jH7/RPf0xvYfCIpD1gHCigO8csOX69UN6iO2Ze4+Qr93LzsMWfXGJGz5h3p08iw9x2vXi+caDjqlX5LemtEKN4EJrovhJoX0bpjg9EG/d6J7JAeQ4BiyDhDWFllNjefXyobiWgRIk0NQmFaKjP0HPL+WVW5wUjXprSkhGTOfcN6857neiS1bRIjDiuXo9010j+QAEhxD1gEiff2Ob1nrk0eOiZjDWdPR79vrDkNWvbGZPHTUt8+AlW5o23bSW1N6UXKykN7hcaPEIadzl9Dvm+geyQEkOIasAwTfluve0ZdtueiiBUaA9F70+/a6w5BVb2y+Enfq8SlwiDXkqz+3H5LemjJ15rxYBZ443lO9RbjBByLcIOVduAHRf5IDSHAMmQeI6Lw5Yltu735Pr9OQluEp+j173WHIrDc2rTrQ1+94dg2YzHBHs0dHzx1N0lteQu1nyzFLu5Pwvim9UyfPCEdz8gT0eya6S3IACY4h8wBhnZbzsDRb9nGdkZi1c6Dj/8wOQ2a9sRmvWS3iTjds9OwaUAKMbzXPmUl6a87w6OFiwnH5umd6xxYZKWd27Ua/X6K7JAeQ4BgyDxC5WNbz05KJLVs9rccqE8khaJ5WHeqxIzy7RnTOLLGqfeAQ6a05of60m3WoG+vN07/06Ubl3wJKcgAJjiH7AOF1AHPd8EFiFn7xKvq9+tFhyK43JmGSAZMNmHRA7JTr7w8Dso/pZkhvuZm+etPKP+nG7kNjvTP3Hov3798T/V6J7pMcQIJjyD5AWCt0HlRpgFmxX/FYMpAcguKEWCk+4Th5xvX3Tl+75Ws+NtJbbvKDbn27GweCHriuN5wy533nsiXo90oUPHv2Sn23bu445OQAEhxD9gECEjPzQXNAL9ffO755s+gglyxGv08/SA5BcSZ27BQxegvnu/7eZrWZ+IYNpDeR04o7ZV/d1jsywahxfeY8+n0S3Sc5gATHkH2AeCWO5YG7p3StU58uBWHLTnIIipOf0m37Xn1tl7b1ueRz194XTnqGurUX27+P6khvIiekAuK7EH27O96FyNebnzJu/2F9bYcPXf0cE0tnIvG8vlu3HvV/+7f/vf5//I//p/6jj9rUHzlyin8Pf79790n9n/3Z/1E/efL0/7+9cwGuojrj+IBT2rFq2zEp7aVIcnMTGNrqOFY7zPiqxVYdGautqWAJAhalVEerguKrFqX4QqUCZVJ8VMeIhWIT8Ym2pQqlPAQBEQIkucnNAylqp7bV1tl+3+7ZsFxuyH1ms3d/v5mPPWf3nM1Zzj7+9zsva8yYC6yzzhpt1de/mFF9+60fIOAE4QOhAzTskWxLl+XtnComu0f/hqD5131hBKG+/bamO+9wBmq8+HLezpl4bZUzwOT2wg0wob6DZ/oDd/f0a8yylxvzVt9tDc85MyjMucv3a/TDmu672xHABTA9dzplWLq03ho//rLu+O7dCVsAnn/+GDuuAnD48OF2Oo03NLxkjR59dkb17bd+gIAThA9EYtVqpxn4puvzNlVL/KmnTP+YRb5fX18ZgiA9c1eG2TPr53k7p/1Bsicbb6C+sYMsXlfnvIsW5dZXz1vfe26ZYfqyrvL9+vyw/iAAN23abp1++hnWjTfebNXVLbOamzsPEYDHH3/8gTI3tVsjR47MqL791g8QcILwgfB2ltaO9Pk45+4ZPzO/ujf4fn19ZQiC9Kwrsc9uAtam4M4dTbmfr7mj++OhYeob81r3YDRdi7zjvZzru3PztgOtGzmcD8vd4vG91vLlK6yZM2+zxaB6+7wC8KSTvtGdtqWlyxoxYkRG9e23foCAE5QPhDtgo/mhB3I+V8eWHc4L8uorQtP8674wglLfflvLwvl5G7ChK9nYzXH3puc5oL7DZ3tuvdFMd7U65/rWUb/2vfv4475fV5ht27ZdtgDUcHv7flsALlxYe5AA1D6AbnoVgNoknEl9+60fIOAE5QPRuafNapw0zvaidDYlcjpX/MknnSaX39T6fl19aQiC9K19/SbnR8K103L+kaATSxdqahnquzise/T5vAdzqu9PPvrIXs+6LwcbYalNB3Scd975tp1zzrnW7Nn3HNIEjAcQfCVIHwhdPsvuR/XM77I+h93p+gbT6fpv+WlODoohCNK3g+6TNeuyPk/3UoNTJ+VtzVfqu/isc1fcGX0+ZYLdBSHb+v7gdbP2753567+K9U9DAELOBOkDof31cvXKuIuj6+z4YWr+dV8YQapvv01/aOTqldF1hf2aa5L6DpbpoCN79PnLr2Zd36133e6c45XszoEFxxCAkDNB+kDYXhkzeCOx6o3M84vgc/O3vfCS79fjxwsjSPXtt9leGXctatOXJxOz77frrvLN20x9B8t02iH7x+n0a7IavNG5zfRt/snkgq2djvUfQwBCzgTtA9H6bL3TxHH37IzzutN72Gtvhsz7574wglbfflvTnDuznr5FvTD5XOuV+i5uO+gHasOKjPPHH1nsDP6Qrd/XghXeEICQM0H7QNgz3E+pyXiKDv1F7XpjEiv/6Pt1+PXCCFp9+23qaXZGjF+ZUd8s+2Nu+hBm26RHfYfP3DlP7SlcMljBo6ul09o1dbIz+GPbDt+vAyu8IQAhZ4L4gXDXVG1ZMD/tPG3PPe94Y2beEErvn/vCCGJ9+2nqudtzx60ZDz7q9jZPv9a3+436Dp7p/eau4ZvJFEQtxvuXmHs39R0SQwBCzgTxA6GeP+2XpV7AdCaG1v4w7nrCYV4YHUGQnek9Zntlrpxoe1p6S6+eGx1k5Le3mfoOpnW8udUZEfzjGqtzV2vv6XUiaZ0ia+I466P2BPUdEkMAQs4E9QPRuuSZA8vD9dJhunX5H5ylvW6b6UtfrP5iCILsreneOc6I4Afn9noPuR5q+37z0dtMfQfXdOS53cqx8PCtHLbH0PRTjS+upb5DZAjAkFBVVTUlGo2e2lu6WCw2o7Ky8iKxWRL+SjrnDuoLo6tjf/ci6i2Le+703LHpbWdZLx2JuXqt7+X2+4UR1Pr229TrrHP5OR30n+sxndtnUL036pmhvrFsrHNns9U4+VJ7FHr7+s09ptNmYts7Pe1yq6ulg/oOkSEAi59BIuSmiQBcJ6Lu9MMllHSjJF2thmU7RNIvS+cPBPmF0b5hs9MUrP2zljxzyHH7o33VFRn3FyxWQxDkZtp9wBZ38mFO1ZWg/Y219kS+vYlE6htLx+JPPNHd9aBj45ZDjrvTxmjzb/vajdR3yAwBGBJEzD3amwAU0TdTRODlnjyt6Zw76C8M2+MycZzTPDf3Xtvjp8JPm31dj41OGcOi6AiCfJj7UbZ/VDz6iNXx1nZ7tY94XZ3TD8tM+twfuhpQ38E27T7Q/PA8534TEdi6ZInV2dhidWx558B+/bGx4gXqO4SGAAwJ6QhAOT5PbKwnHi8tLT2qt3PrC2PfPudmCqolVr7W3cybbM3332PtTbzrexn7g2k9F0N9+2l7935gtdU32GtSp7rfWp+us9P4XU7quzhsb9f7VsuCh1Pea+ptblvxPPUdUtN6zoe+gH5Omh7A+bFYrNoTb49EIkcWvnT9g+01Fx7bOKH6vp0Tfrh954TqbY011a++U1P9Lb/LBcVJY833T5R7rFZsy86a6ja57xbtqLm41366ANmwvebiUfJeWyrCLy7vufVyvz3aeOlFafXzBoB+igi100TcrRFb7bE13j58GTQBT/LEE4UsNwAAAAAUkFQCUMRehTcugu8U9QJqOBqNSvLK+r4sIwAAAADkCRF6U0XMbRV7TMJnmt0DJL5L4sckpZ0tIvASsTkVFRWxvi8tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRIVVXVlGg0etAKBrFYbEZlZeVFYrMkzGzzRYjU+wmyOUKXC2TKoOKDZzhc8DyHh+RvNs86ZMMguVmmyc20zjvJtOwbJftqNSzbId4VSaB4kHp9U+p3n9jySCRS4nd5IH/wDIcPnudQcMg3m2cdciJ5lRGzpNzlnuOt/pQMConUc43fZYDCwDMcPniew4P3m82zDjmRLAAlPE9srCce12YFf0oHhcKsFnOubG8qKysb4Xd5IH/wDIcPnufw4P1m86xDTqTwAM6XXxTVnnh7JBI50p/SQQEZoP+UlJQcLfW/xu/CQP7gGQ4lPM8hIckDyLMOqZGb4TR9GYit9tgabz+BHpqAJ3niib4uN+ROD3WvtqyiouJ7cnyuSTpQ9n3oa2Ehr/AMhwvzPN9vojzPRU6KJmCedciOFALwFP1VoeFoNCqHKuv9Kx0UAvlgnCV1e7KGy8vLh0sdv+x3mSB/8AyHC57ncJEkAHnWITvkl8NUuWG2ij0m4TM9+2fLTXWJ6VfClAJFiHYc1l+OUve/YNRg8cEzHC54nsNBqm82zzoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAMKmqqpqQ7hJisVjsdklbl83fkbxnyN/qyCYvAAAAAOQRIwBXp5PWCMCnsvk7RgC2Z5MXAAAAAPIIAhAAAAAgQ0QQXS8WF3HzD9nuEqFT7Tk2XWy3HHtXtr8fNmzYl91jsq/J5N0g4X/KdmlZWdnnJf/jEv5A9m2W8Eg3fXl5+WDZ97Qc6xRrUTHWU5kk3bOSZpGnHA+IvdRD2oMEoMTv1/Pr9Yit964XbgTgMtn/hLneLd7jJSUlR0v812KtKvYk/a9k9yCTFwEIAAAAwScajVaJ2PnQXYdTRZqIuBEalv2XieDZowu1i/j5tMQXSPwvbl4VgGLrJP2XjjvuuC9IeIfYO5LubDk8QLYPeUSbxtfqeq8S/pTmUeEo552cqlxDhgw5Vo63yfEL5JyjVTRq2VKlTRaAEh6r5ZHgQAlfLdYlf+8zekwFoKT/WPaN0+MSrpHwe3KNnzN5l4ktHjx48Gcl7TFy/AWJzzJ5EYAAAAAQfETQRFUAyvZCVyS5yP5XxK5y46WlpUepeBo2bFi5yasCsMaT/iGJP+/GRTCNkn17TdpTxBLe88vxH8m+V3sqmwpJza/eOEk75jDXcNgmYDm+X/KfaP6mCsB1SX9nowpCOVaq16fiz5P3NPWAmrwIQAAAACgORNj8QETOn7TZVqxBvYK6X8JvJwsvHQUrx0814SY5/h3PsV9Knkc88RMk/i/zNy6W+H9VjKmp103sfQm/dZiiDTRexe2HK3+KJuDrtOzmb6j9z3glu5uAk/Ivl303yHWdLNtP3DKacr6v/y8mLwIQAAAAigv1AJpm2z9rvCcPoKQr03gmAlC239Tm5EzKI+e+Tad3UQ+dhK/tKZ1XAKrHTmyfpP+q5/h+t5w9eAA3qAdQm5hl+x/ZdUQP5UEAAgAAQPBRb5/Yt7WPn0SPkO1dInJe02PaB1CbP7UPoIpD2T9f7HU3b5oC8N8mOtD0AbwlEokcKfEB2u/QOwDDixGMf9fmZh1Iop48Sf+1VGm9AlDSnKteSjNYZZDsv1k9j+jytsQAAADSSURBVEkC8GOxS8z1jtdz6+AV83e1D+ACNy7nGyppvmvyIgABAAAg+Ii4+7oInr+aUbva7LnSbQIWBojomaGeO/Wq6cjcoUOHRty8uj9dD6AiYuqLOkJY+wKaptkN3hHHLtoHT441qrBz96kn0jQXD0pOn9QErM3GteZ69O9c7y2naQJeKvt+a0YBb1Vh555LvZymL2Ozaf7dKuGfmrwIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAID+zP8BGTvNbnrQ2rYAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9Z5QkSXIeuLMLgDhwIXic4QKzqqe7qgCShwNxjwvevgNAEvcAHn7c4wK4nR3ZWmutdbXWWotqrbXWWmstKiu1bDGzs1rN1Lm5R0RlV1dWZmQIcw+3772vS2VnWMSX7m7ubm72pS8RCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAILqOqqurHlZWVf1vkNZGKior2Tq7DrjGbMcfe60fsvf6jk/cqBvb+/5Vd6wv27ZfdfF/2nn/P7H/Mvn7Gvk5mXz9gXx+5eQ0CgUAgEAiEZsEckHbg6DCHZ1Kx1zJHpQ17baK51xRynJw6gOz//p/sfX/RokWLPy73PQqBve9qZt/aRteD+/j8Sy47gOD8sffu7+Z7EggEAoFAINgCc0iuMkfnGWOW/fjbzb2WvaYtY7y51zDn5r8ZjtNXGl3HqQP4UbFrl4Am789nB/DXrVq1+js337MENKsrgUAgEAgEjdCyZcv/DE4Oc3b+AVbXYDuymdf+Nfv7zxl/A1u+sA3Lvn8f/gYrfuDUMH6Tff8zeE/zNey9h8JrGjuALVq0+DP2un3geMKqIvv7wrfffvv3mro2+9vY/Guzr/cMm/6Qvecy+P+GE3uA/a7K/H/sb2PY68+x349nX1Ps6/0m3nsY468Yf5ln8zdMB5DxX9jvnsCWLePRb3/723+S9/7/ClZO2e9D7DUv2dfTjP+pwPOrNGyH9/wZXIc9r/+r8arqW2+99VX2cw37/QtweBl7G8+ntXHN11ZYG7+H4dBuYV8Xmc8Ffv/Nb37zbfb9Bsak8dw3sGf+ZiHNCQQCgUAgBBDgKDDeML7fxJyG88293nA0XluFMx1A+D5v5eyNRv/XcgC//vWv/1vDMenNfvytb3zjG/8rOFeMS+1cGxxI9vsT7H3fYg7l7xoxgnHTkTQcwF+x341gP/4OvKbQcyiwAvgF+/06cMrefPPN34fnA6/N+381eU7hl9n/6Q4xiuCYFroP41n990L3xb5fxXj5nXfe+RrYy/6+3HBO8x3AV1Ymm3iP1cb/acN+/Ipx378DsYbsb1PhZ3hG7L3WgP2FbCUQCAQCgRAwMCfgj9jg/1PmFHSGn8EpAceCOS9/Xuj/2HQAC8YAsq/9GjubsBoGq5BfauQ4Fro2xAIa1/3f8l72W+x1z9n7v2tcZ0yxmEXD/oJbwOz3X8/7HTh4D+B7w4mF61c0eq+nza2k5j+rJu7rDXgG7Dr/w/w7OJ7GyqddB/BC/nXZz//U+FnAvYE9sDLY3PMhEAgEAoEQEMBBBNiShNUt41dvGM7L4kL/xy0HELYmjRWqT0yy3/0QHNL8Ldbmrs0c1e/AdRpvG7PXXWe/H2jYMqbYqqZhT0kxgPk2sO//ylghzL+HT9nXn7Cvg5u5VkEHkP3+38HfGf99o3t6btcBZFzf6LqDIf6wsb3wzOGATbFnRCAQCAQCIQCAuDbDCUszZoDGiuCP8pzCV8AchY+LOYDs//9NCSuAo9nPx23a29QKYOMVy6/A1jJ7/+8b14EVwLPF3pu9ZqVdB5Bd91uVIn7yG3buo5QVQPb3/yfPjj9otAL4f8B1YWUw7z2GN7EC+Mr9wP9nv6+1YyuBQCAQCIQAwTj0AYcR/hZWnfJYAauC7O89mvp/7PV/DwcYIGav0e8tpwYOOxiO0X/If02+AwiHReDQBGypsvf6X8zfsZ//ZyGbC8UAQgwb2A7vw14zE7Y5v/a1r/1r4z5LcgDZ6yYaW6ZfzvtdKSttOxj3gDMIP4NTBs4bxO8VulYRB9CMAbwIDi6sbrLvl+THABqHRH5orHKCw/if4NkWcwDh/7HfRdnfxoNTCb+D52ZulxMIBAKBQAg4mBOwk/Fwgb/BQYrXTssagBU2OCzywthGfM/4P5/nOzWVDQmbPzG3Q9n34fxTwHBaF+yAFUhjK/K+cVijSTTlAEIco3EKOGlskx5kztefmn8v1QFk/+fb4ACaW6P5p4C/1IwDaJwCHp13ShhO125vLldh42fV+D3zTgHDqWI43dyLMZvvqIGjDKt5xknsA3DSupgDCIDt9UpxcCVmOJFP2f+dX+z5EAgEAoFAIBB8hHFYB1Zr/wu2LQQCgUAgEAgED2DkUoSyel82ThrDiiuUinM1ITWBQCAEApDKAhLVNveaioqKIawz/WfGaruB2wQCgeAHWN/UivVndypFrWBIBg3JrSux7SIQCATZ8DsQsM46ymuVzRSjZ6/5LiRUhe+N3Fc7/DORQCAQCAQCgeA6jLxXBR1ASJPAnMCOea8vmhyWQCAQCAQCgSAxijmA7G/zKo26pcbP8UK5zggEE/fe+5/ffNrmB6tr27x742nrdxNP27y7/VHr738X2y5CMPGk9ff/urb1u8vYZy5V2/oH95+0+cGK2tb/8pfYdhGCiccff//v2OftxNPWP3jIPnOPWD8341Hrf/q32HYRCLZQwgrgwvw0CpB6olDh+Xx88cUX9QQ98dnpE/WhLm3ra9v84DXmVi6p/+Lzz7FNJAQE0M+83LOzyc9abYcP63948lg99UUEt/D5L35en54/s8nPW13XtvU/vnIJ20RX4JZ/QZAcJW4Bt8/7OVXK+8KH6MWLH9U/f04MOkFnU+/kgUNWhxhbOK8+e+9xfS4Uq09s3Vof6tpO/H7BvPpnuR+i2010rjemHc+efVYfW7JYfN7af1Cf2LypPvskzD9z8ZrV1ucwvm4d+jNTmbLojc1n2U/rI1Mm8s9UqFuH+uTuPfW52mh99s7D+ujsGeLz1u6D+vS5i+i2OtXbDd+CoAAaO4Bwki7/71C3E1YB4XujUsHeUt4XOgzeaJ4Rg07QGZC5eoMPxNARJo8ce+11mZv36msNJxAGZWy7ic70xm7fyb37xaDbpW19+uKV1/6eOnOerwLCa1JnLqA/N1Upi97YjC1aKJy/3l3YRCPy2t8TW7aIz2PHj+vTN+6g2+tEb3e9DIKUYM5eN6OKQA37/r99SZRHCpnljvJeNwkqFzBOgZJXpbw3dRj6EHT+zU9+XB/q0VE4dxs2Fnxt+vqd+tq277GB+aP67NMouu3E8vTGbt+ZhyE+0HLn7uzFgq8zncRQt/ZNDtpENfTGZvrCFWuykbnzsMnX5HKf1cdWrhTbwYP71ecyn6DbXa7eXvgbBI2ge4ehE7nOG2p4xwdbJNARNvd6cyYdnTcH3XZieXpjtu9c9of14dHDRTjB0iXNv5Z9FqNzZonP5vQp6M9ORWLrjU34DIVHDeOfocTuPc2/NvNpfd2wgeK1W7eh216u3tj+A0Fx6Nxh6Mbsgydi65cRVmaKvj6UqK/t1JqvBGZuP0C3n2iP2A5B6vgpscoyoFd9Lvm86OtzsawVf5q+dgv9+alGbL2xmTp9Tqwi9+1en0sXX9WDz5i5FaziqjM5gATH0LnD0I2RKRPE1u/qVSX/n/j69WJVZsI4dPuJ9ojpEMDqX93gviLO9Ojxkv8frMbA/wmPG1V0hZooj97Y5J83Y0UPDriV+v+iixaIFeoli9HvoRy9sf0HguLQtcPQjZl7T8RqTI+O9c8SuZL/Xy7xrD7Us7OI4TpXOIaLKB8xHQJw+kSMVV8+OJf6/3KpF/Wh3l2NmEE6EKKK3thMHTspPm8De/Pt3VL/X/ZxWMQ6d25Tn4s/Q78Pu3pj+w8ExaFrh6EbYytX8A7y+aZ1tvVO7hMB+nVD+tsazIm4xHIIYOWubpBY/YOB2e7/T+zZZ8WpYj9DlairA8hX/wb1sb3abNJMGZPYsxf9Xuzqje0/EBSHjh2GbsylX/J8WNDJ/TKdsq03D5g2t/MOH0W/H2JpxHII0ldvNsT+lTFhgJUYfnK43fs8DhX7OapCXR3A5MHDjiaokHqI//+hA5QKOyAHkOAYOnYYujF59IQVV1Wu3uZ7RCaMRb8fYmnEcghiixeJWNONhdMMFSOcPFf5hKZOemOSr/717ylWm0+eLfs9Qv16iMNHV26i35MdvbH9B4Li0K3D0JHh6rGigzx8tOwBAmKzajuLE8G0KqMGMRwCvtpsnOSF+Kpy3yd96VpDDKFCqzK66Y1Na7V5kLPPSWLLVpHyas4s9Huyoze2/0BQHLp1GLqRJ+KFVAdsUH6WfuFogIjOnS1WZXbuQr8vYnFiOASpE6fFavPYkY7e55VVmevqVmsIut7YjC1fZiS13+DofbLhVH1t+w85s+Ek+n2Vqje2/0BQHLp1GLoxvkYkfo4tW+p4gIBKDnxwHzUM/b6IxYnhEEASZx4rum+/4/cyUxDBljL2s1SBujmAfJLQqwv/jGTuP3H8fuYEN755C/q9lao3tv9AUBw6dRi6EUocmSlcMrcfOh4g+Pt1F4dJso/q0O+P2Dz9dgiy0YxINN7hQ57U2fH7QYoOo6xXLvUS/XnKTt0cwPTl69bhDVfe7+qthkTSCmQ7IAeQ4Bg6dRi6MXXyjFixGznU6jCc6g0JU/ksedMm9PsjNk+/HQJIo8EPCs2c5tp7hqvHlJ3eQzfq5gDGli1xtS/i6YuYM1msbrUsJAeQ4Bg6dRi60az8kdx3wOownOqdvnLDKqKOfX/E5um3Q2DW/U2dKu80ZlNMHjoqnMqJVIlGNr0xybd/zd2NB7WuvW9i23ZlKoOQA0hwDF06DN0ItVfNoGYzw70bAwTvePt0Ex3vnYfo90ksTD8dAvOwEeSbLKUOa6nkn+PObcTp86dR9GcqM3VyAK1T4sMHufq+mftPG7aBJT99Tg4gwTF06TB0o1kYPb+Gr1sDRGz1KrH1UlODfp/EwvTTIbAObCxd4vp7RxfMo9PnkumNTSsUxeUDG3wb2MgrmLn7CP0+i+mN7T8QFIcuHYZuhIGYD5rbd7zSYbihd+bWfWVmyTrTT4fALMWVvn7b9fc2U8tASAP2M5WZujiAUJko1KOjcNIehlx/f8iYoEIScnIACY6hQ4ehG/kstp8xi73XkB7BrQEiv9YrnJzDvl9i0/TLIcg+iYgJQc/OnkwI4EQxlIWD8nCQaBr7ucpKXRzA9MUr4nDbiMGevH/q3EWrchL2vRbTG9t/ICgOHToM3QhB0U2t0Lk5QMTXrRNbMOwr9v0Sm6ZfDkFy/0FRRWHubM+uER4zQkw4Ll5Ff66yUhcHMLZ4oacrdJByyKxF7UY6Iy/1xvYfCIpDhw5DN0KslEigu/C1DsMtvc0gbBiYse+X2DT9cgiis2eK0+YHD3t2Daj0QHGncuiNSZjQhnp1NkoNepeLNDJ1kjjRfuwk+j03pze2/0BQHEHvMHRkZHJ1k8XR3RwgYCtOzJI/qM8lnqHfM/F1+uEQ8FPh3UU8VrY25tl1ILbQi1OfQaIODiBU/OCfgwG9PL1OYs8+sao9bw76PTenN7b/QFAcQe8wdGMu9aLBMYu/6pi5PUBAbjbuaJ65gH7fxNfph0OQuf3AyAvZ19N74Y5m13bC0VSkVmsQ9cZmYrdINh5btNDT61hxrT06SlsVhBxAgmMEvcPQjVYA8/jRTXYYbuqd2LJVdMYrV6LfN/F1+uEQWIlzly/z/H6iM6eJrebDR9GfrYzUwQG0PgM+VIapG9JfxJ3euIN+34X0xvYfCIoj6B2GboytWC4CpJlz1lSH4abe6Rt3xerPsIHo9018nX44BJGJ48Uq8Olznt8PVLSRfVsu6HpjUoQbGLXIQwnPrxevWS3iTtevR7/3Qnpj+w8ExRHkDkNH1g0U+dgyt1+v0uH2AAEdcq25LRdJod870Vu9X9M/Pw407n0cqNfpZlRn0B1AqDzEJ5yDvA03MJm+fN2opT4E/d4L6Y3tPxAUR5A7DN0Ip+L4ANmrS5MDpBcDRGT6FOlPy+lKrx0CSMnCB8ix/p0ENxNONzXB0Z1BdwCt7AY+1emFhNPWBLdOvrhTcgAJjhHkDkM3JvaIAGkonVWow3Bb78SuPUbKmUXo90/0Xu98xtes8X2LDGINVajSEES9sRmZNllMNo+f8u+aRsyhjBNccgAJjhHkDkM3Wh1kgc7KiwECKo34kZaBaJ9eOwSwNSaqwdz07Z7gxLmocT0W/fnKxiA7gK+cAvcx3CSxY6dvh5zK0RvbfyAojqB2GLqRJ0g1A6TDTXeQXgwQryRmfRpFfw5Eb/W2dI9m6mvbvldf27lNfS7ziW/3lEs+r69t/0F9bYcP+ffYz1gmBtkBNOuPw8lcP68LJ4C9LDvnVG9s/4GgOILaYehGKIpebCXOqwECSoDx1AwHDqE/B6L3egNhG46vxE2d5Pt9QYojvvJ44Qr6M5aJQXYA/Uw3lE+Y3Fhl4SSbcJADSHCMoHYYuhHKcBVLkeHVAAGOn9e1YIn26aVDADGfPBZv5y7f7yu+dq2IPdy4Ef0Zy8QgO4CRKRON6kZnfL+2NeGQrA41OYAExwhqh6EbrQF5z75mOwwv9LbScxQ4fUzEoZcOQd3gfuI07t1Hvt9X6sx5sfo4ZQL6M5aJQXUA+WncLm15yAGEHvh9/fha47DTpk3oz6Kx3tj+A0FxBLHD0JF1QweIAflO4fQYnjoEA3qJ699/iv4siN7qnYvnRPwfG5QxymRlI2kx4ejWgSYcPuiNTTMOD6sOtHXwaHI1+rNorDe2/0BQHEHsMHSjNSBDQH4zA7KXAwSknqE4QLnold4Qe4d9EteacDyoRX/OsjCoDiB2yUl+4IldH3ICylQXmBxAgmMEscPQjenzl40BeVzRDsMrvWHr2c8krcTi9Epv2ArjW2Jr16DdG8S68gnHoSPoz1kWBtUBjEye4Fu5wULEDHloTm9s/4GgOILYYejG+IYNYkBet65oh+GV3maaBhnTJehKr/SGk7/YA3Ji916acPikNzZDPTqhl5uMLVpYNMYaQ29s/4GgOILYYejGyKRqMSCfu1i0w/AsL5yVLuGD+lzqJfozIXqY99EckMN45bGsvHBIcWEyMogOYDYUF/Gefbqh2lFKlgUMvbH9B4LiCFqHoRshJoWfkGOdUy6WLdpheFoZYswIozLELfTnQvRG7+zjsBiQ+/VAvTd+MlTS/GxB0hub1gEMhHyT+bTyrPbvif5M8vXG9h8IiiNoHYZuhJgU3jEN7ldSh+Gl3rEVy8U2yY6d6M+F6I3eyaMnxErI7Bno9xceN0pMOC5dQ7dFBgbRAYRcj37Xm26KYuW7o1j5rsNb+W6sN7b/QFAcQeswdGNy3wExIC9cUFKH4aXelnMwZyb6cyF6o7dMTn68pkbYsmULui0yMIgOYGT6VBHecuqsBLZMEbacOI1ui6k3tv9AUBxB6zB0o530K14PENnHddJtk+hML/QOjx4uVt2u4W/zp06eFduD0yaj2yIDg+gAhvp2l6bOeGLrNiMdzQp0W0y9sf0HguIIWoehG+sG9TESMD8pqcPwUm++TdK9g3FiL43+bHSn23rn0p/U13b4sL62vRwHfWArjscj9uhECaE90BubZv496FNk0Bdim3mmg1HD0G0x9cb2HwiKI0gdhm7Mmh1kt/YlJSj1Y4Cwcnadbf5EMtF7uq13+sZdMQCOHIJ+bybhMAqfcDwOo9uCzaA5gFB7t5T8pn4xl36ZNwF6gW4POYAExwhSh6EbG0oUlVYT1Y8BwspJyL5iPx/d6bbeiV27xRbYsqXo92YyOnumCIE4cgzdFmwGzQFMbNsuPm+rV6HbYtIKgbh+B90WcgAJjhGkDkM32i1S7scAASt/dpxSond0W+/o3NnC2Tp8FP3eTCZ27hJOwvJl6LZgM2gOYHTOLPF5O3oC3RaTkHhcJITei24LOYAExwhSh6EbrQTQ5y+X3GF4rTfE/skUt6Mz3dbbqr/7MIR+bybTN+4Y29JD0W3BZtAcwLpBfY16z0/RbTGZ3C+yLkBlEGxbyAEkOEaQOgzdaLdEkl8DBJwCFnFZdejPSGe6qbfl2HeTy7EXB1M+kuZgSlD0xiYk965t+159befWJcU3+8XMzXvSlLwkB5DgGEHpMHSjVSKpd1dbHYYfekMeQNm2bnSkm3qnztqLN/WTcCqTx2XduItuS1D0xiakGeKO1tgR6Lbkkx8EYZMNOAwC5S+x9cb2HwiKIygdhm4sp0SSXwMEJAnm2yQrlqM/J53ppt5QiUHWwz1mXBYkRce2JSh6YzOxe4+0sZ1Qf5pvTd9+iK43tv9AUBxB6TB0Ixz84APyunW2Ogw/9LbyZY2Ra/auG93UGyYaIr3PBfT7aszk3v3CWVi6BN2WoOiNTahsVGqCe99tM5PvHzyMrje2/0BQHEHpMHRjZOY022WJ/BogIBartt0HPDYLe5tEZ7qpd6hPNxHXGYqj31djQkoOmnAEywFsWGV7gG5LYyZ2ybE6SQ4gwTGC0mHoxoaDFqUnwPVzgLA68Du42yQ60y29rYTj3TtKdQDEpKwHBlTVG5swaaxt/yGnjBPI9NWbRnziSHS9sf0HguIIQoehG3PxHO+Aaru2szUg+zlAROfPlS5nnG50S+/0pWtSVWRoilbKEIlS1KiqNzZh1U+Wk7ZNsWHC0QZ1wkEOIMExgtBh6Mb05euigxw/2naH4Zfe1kGQVfJk8deNbundoOVK9HsqRLMiSOr4KXRbVNcbmxD3B1pGFy1At6UQrRrsD2pR9cb2HwiKIwgdhm60qh/YPGXr5wBh1fGcKO+qUdDplt7Wau4heVdzE1u2ikNRa9eg26K63tiEUoO82sbuvei2FKKV6uoYXqorcgAJjhGEDkM3NgzIR2x3GH7pbSUO7tkZ/XnpSrf0tuI57z5Cv6dCTJ27JCYcU+TLU6ia3tiEwzw8r+O1W+i2FGJi6zYx4ahZjao3tv9AUBxB6DB0Y92wgWUNyH4PEKHeXcRBlXAS/ZnpSDf0lj0g32S2LmkkRu+CbovKemMTYupqO7XmMXYQa4dtTyGmL15B3+EgB5DgGKp3GLqRl74qMxO93wMEVI2wU6uY6C7d0BtOcYOGsAqIfT/FGOrV2ZhwlFYaMWgMggOYuf9UfN4G90W3pTk2nIzHK41IDiDBMVTvMHRj5tb9sk/I+T1AxGtqRCzPtu3oz01HuqE3xP3xgPwF89Dvpxgjk6vF1qGmE44gOIDJo8fF523ubHRbijHUt7uYcDyNoumN7T8QFIfqHYZudHJCzu8BQqXOPIh0Q+/YypXCid+xE/1+ijG+xphwbN2GbouqemMztnqVMpPGyPQpYofj1Fk0vbH9B4LiUL3D0I1OTsj5PUBk7j0R2zlDB6A/Nx3pht6RCWPFqtqla+j3U4xwIpNPOObMQrdFVb2xqdLnLb5xozgIsn49mt7Y/gNBcajeYejG8NjyT8j5PUDkMp/yWEWIWYTYRexnpxud6g2xTVD9Az5vuWgG/X6KMfPAjB/rh26Linpjk3/eunUQn7dYFt2eYkydOS8OgkydhKY3tv9AUBwqdxi6kZ+Q61z+CTmMAQJiFUVNTyoJ5zed6p2tjYtA9z7d0O+lFFonSNu9X59LvUC3RzW9sZl9EhGft3490G0pyd4QbvsgB5DgGCp3GLoRylzxFY5BfcruMPzWGw4PlJOzkOicTvVOnb2AusJRDsOjh4sV8ht30W1RTW9spk6eFZ+3GVPRbSmV1go5woolOYAEx1C5w9CNqWMnRYzT7Jlldxh+661CGbGg0qne8c1bRIzTunXo91IqY0sWiwnHvgPotqimNzYhlo5/3jZtQrelVIbHjUJLWk0OIMExVO4wdGN87VpxAGTLlrI7DL/1hmBuPqufQCXh/KZTvaOzZihXXze5d7+YcCxdgm6LanpjE1aa+eft7AV0W0plbPEiMeHYfxBFb2z/gaA4VO4wdGNk+lTRQZ4+V3aH4bfeOTNhao+O6M9PNzrV2yp4/zCEfi+lMn39jsiTOWYEui2q6Y3NUO+uIq9eKIFuS6m06rKv9H+HgxxAgmOo3GHoxrpBfR0NyFgDBARJ8469jkrC+UknesMhIzhsBIeO4HAF9r0E3W5svbEJ1Vv4RLGXWrXD0xeMknCT/a9BTQ4gwTFU7TB0I6/J2g5KwH1U9sCGNUBEphgl4c5dQn+OOtGJ3tZK2ujh6Pdhl3UDeokJx5MIui2q6I1N6BuwHCkntE4C9+2Ooje2/0BQHKp2GLrRjaTKWANEfM0arSs0YNGJ3sl9RizdksXo92GXVizZuYvotqiiNzYhrpkfAFm7Bt0WO4TchbVd2oqTwGWk5nKqN7b/QFAcqnYYujF14rRxAniGow4DQ2/dKzRg0YneseXLyq44g02rnJgC5etk0Rub0VnThdPO+jlsW+zSTD2UuXnPd72x/QeC4lC1w9CNkBqBz5A3bHTUYWDonblvrF4O6Y/+HHWiE70jE8crU5KrMc162bFFC9FtUUVvbFrb9o/r0G2xy+jC+Uau06O+643tPxAUh6odhm6E1TOnKTmwBgheoaHDRzyGEWIZsZ+lLnSit8oHd9LXb4v4xbEj0W1RRW9M5uI5rldt13Z8SxXbHrtMbNsuJudranzXG9t/ICgOFTsMHVk3fJDYZrj7yFGHgaU3xC5y++8/RX+WurBcvXOJZyKwXdEBGaoycPu7d0C3RQW9sZm+fF047ONHo9tSDq2KOdMm+643tv9AUBwqdhi6ka+gdfxY1DhNl7+ChjlAWEmFT55Bf566sFy9IZZJ1RPAJkO9uogVzEgK3RbZ9cZmQy69Fei2lP6riOEAACAASURBVEOzhnHdwN6+643tPxAUh4odhm7MPg4bHUx5NYDzOwwsva0yT5vLq2JC9E/v5OGj4tDOgnno91Auw9VjRQzjlRvotsiuNzZjixeKGLoDh9BtKYfWBL3te2yC/tJXvbH9B4LCeNL6+/0/PXJAuQ5DN6bOuLPFgDlAJI8aJ4HnzUF/nrqwXL2tkoMKp+2JLVti1ATej26L7HpjE7Z+serpunYPIwaLEJc7D33VG9uHICiMp61/8BxmLc98nLUQ7dOtIGPMASJz+4HYVhw1FP156sJy9Y7McFZyUAYmdu8R24orlqPbIrve2Az17Czy6EUz6LaUy+jc2WLCceyEr3pj+xAEhVHb5t0bPE7m3mP0BkRspnNxKc0A5gCRS70QJbq6tFXyYIGKLFfvusHOSg7KwPTFq2LVfFI1ui2y641J68BOj07otjghhLbwSfr69b7qje1DEBTG0zbvbuIz/VMUmC8z3Uo0ij1AhPr1MIq9x9GfqQ4sR+9c5tP62vZQcvBDpWvpZkMJtBJdKumNTStlz7hR6LY4YerkWRHiMnOar3pj+xAEhfGkzQ/GiVifregNiNg0eamhru1cKTWEPUBEJleLWJ+LV9Gfqw4sR+/Mg6eBSNrtZrtRhdjtuxwmDx4WW/WL1U7anXlQK9rN4H6+6o3tQxB8QEVFxZDKysp/Zqxm33+j0Ouqqqr+gn35yltvvfXVVq1aVRR739qPfvAhb3wL56M3IGLTdHMlA3uAgHgsVcuLqchy9E6d8n8lwytilehSSW9sxmtqAlG2j6+cd/iQr57D937p7aqjQZAPzOH7LnPslsP37OvXmRO4o9Br2d9usde8YNz19ttvv1nsvZ98+IPv6JgxXyWmL15xLZYJe4BI7t0vZvvLlqI/Vx1Yjt6JLUYs07p16PY7JaSx4bGzh/0t0aWS3tiEzAY8DOnsRXRbnBJWzf1Mdk8OoAZgztxw5gR2NH9mTl6imde2tvPet773vT/iq0s91Q7ADTITu9w7zYg9QJgZ/yMTxqE/Vx1Yjt6Qpoc7TUePo9vvlJDGhjuza9eg2yKr3tisG9THqAEcRrfFKa1k9ydO+6a3E9+CoACYwzeP8f28n+OwxdvUa5kDOKVVq1b/yL4Oa9GixZ+V8v7hXuII/rN4ln+giHIxttTIZ7b/gOP3evFCDBDwFeNecpGU2M7u0w39uerAcvSGND18FeP2fXT7nTJ95pzYzp4xFd0WWfXG5LPsJ7w+ONQJf5b7Ibo9TpnYsEFsZ2/e5JvebvkZBEnBnLmFFRUV7+b9nH777bd/r8DL34B/3nzzzd9njuKlUt4/MVEk4fx5OFRPkA/JKeO5Pj97+hjbFMf44osv6uu6d+D38/nPf45tDqERuD5d2/J0PZ//4hfY5jjGr3IZ4QAO649tCqEJ/DItJoSxkYOxTXEFP75ySUyelsz37ZouuBgEmWFsAbfP+znV1OtatWr1Pfa3mcaPX2YO4E9Lef/sisVi2frIMfQZFPF1WklSYxlXZowAzBWC8BgjMP/WPfRnG3Ta1TtXFxcnGft2R7fdDcKqEg/Mb/cBX23Ctkc2vbGZNg8czZ6BbosbzN57JFLaDB/km94uuBgEmcGcur+CVUD4vmXLlsyvq9wL3zOnsFX+65gD+Hfs79+B7995550/Za87Wsr7f7J/t+8JLImlETLju5kkFToNAHzFuicrqbUmgfmYtKu3deBocnCSJ9cNHWAE5j9Bt0U2vbFpHTgKyNiTS8OW9vu8LrAfOTRBZ7f9DYKEYM7eJOYEvmfE+EF6lzeYgxdiv/+DRq/rCKuF7G/jSzkFDPjx9SvGLGwmegMivsr01ZtiRjl+tGsdBvYA0RCYvxb9+QaddvW2DhytXIFuu1v0OzBfJb2xGZ0/NzAHjkw2HGqp80VvTxwOgj74RVJs+0Axa+zGQ3yVcPCDD8hLFrvWYWAPEFBflq8yzZiK/nyDTrt6x5YZB4727Ue33S3C6hKfcGzahG6LbHpjMzxqmBEOch/dFrcYmT5FTDjOnPdFb2z/gaA4Pv/lL0WN1s5tqEarZIytXClOle3c5VqHgT1AQH1ZvzPm60q7eoerx4pKLVduoNvuFpPHTogdjrmz0W2RTW9MBrVSC6QcEtW1tvmiN7b/QFAc0GFA0Leo0ZpAb0DEBkYmTxAD8oUrrnUY2AMExMbUtv+Q06+M+brSrt6h3l1EPxBJodvuFjN3HmqzwyFD+y6V2bqklRIK2xY3mTxyTEw4FszzRW9s/4GgOKDDiEwcJxyNy9fRGxCxgSHTMa+Nu9ZhyDBAWBnzH4bQn3GQaUfvXDwnBuTuHdDtdpO59Euxw9GptS+B+arojc30pWsiFGRisJLCw3Y2n3CMGuqL3tj+A0FxQIfREPtzAL0BEQVhW4QPXF3aurY1L8sAEZk5TcTJnD6H/pyDTDt6p6/fqQ9qWci6Ab3EROpJBN0WWfTGZmLPPhHfvHwZui1u0uq3fQipIgeQ4BjQYSR37RKNcdUq9AZEFGyYSQ5ztcOQYYCAE8B+xcnoTDt6Jw8eFltXixag2+02I1MniQnHOfXrzbqlNzahtCXvA3bvRbfFbdb162ns3MQ81xvbfyAoDugw0ucviuX4aZPRGw9REPLkuR1LIssA4WecjM60o3e8pkYMyNt3oNvtNmOrV4l727ET3RZZ9MZmZFK1CDu6eBXdFtfvbYqI3U6dv+y53tj+A0FxQIcBOYv4ycxBfdEbD1HQi9NksgwQmZv3xOrm6OHozznItKM3TP74oHX2ArrdbjN54JDY4Vi8EN0WWfTGphXfHHInvlkmwk6aHxMOcgAJjgEdBi+ZxE9mfhD4QGlVGJk+1fV8UrIMELnEM3HgoGs7Sj3kIe3oXTfQTGAbRrfbbaav3xYTjnGj0G2RRW9M5lIvXI9vlol+TTjIASQ4htlh1A3uKwaAR95nMCcWp5VR3kU9ZBogIP0Dv79wEt2WoLJUvf0uYeU3c7GsccK5I7otMuiNzcxtIzXPSO9PymLQrwNV5AASHMPsMBq2gIIdKK0Cc5lPeAH72g4fuTogyzRAUOoh71mq3pl7T0QIyLCB6DZ7xVAvM8dhGt0WbL2xaSXnnjcH3RYvaKVU6tbe0xVOcgAJjmF2GFagtEtVJ4jl06sBWaYBAtI/8M/bnn3otgSVpeoNdXKDXg88XD0mcFVOytUbm/ENG0R5vs2b0W3xiqHeXT3f4SAHkOAYZodh1Z1dugS98ejO1PFTngzIMg0QkP6Bf95WLEe3JagsVW+ok8sHZDYwY9vsFaFfC1qd43L1xib0a3y3iU08sG3xitYOx6VrnuqN7T8QFIfZYcBWHE8FMyFYmdlVZHzjRmNA3uh6hyHLAGFVAphUjW5LUFmq3lAnlw/Ix06i2+wVE7v2BH7CIVP7bo51wweJSkD3nqDb4hWtHQ4P8xySA0hwDLPDsGoz9u2O3nh0Z3SOMUM+fsr1DkOWAQLqTtPnzVuWqjfUyeUD8t1H6DZ7xfTFK4GfcMjUvguR1wLv+DE/dASHj7Dt8YrJvfvFhGOZdztq5AASHMPsMCBYFY7lw/H8XOolegPSmRD7J2bIj13vMGQZIF75vCWfo9sTRJaiN9ehU2uhQzq47R7yzQV9wiFT+y6ow5OIiG8e2BvdFi8Jsab8JHD1WE/1xvYfCIojv8PQYSVAdno5Q5ZtgICC6fzzdus+ui1BZCl6Z59GxYA8oBe6vV7SmnCwew3qhEO29t0UU+cuiZXYqZPQbfGScNqcTzh6dfZUb2z/gaA48jsMa+sxwMG5stOqyjKwjycdhkwDRHT+XBGYf/Q4ui1BZCl6WwPylIno9npNqKvNJxw376HbgqU3NiHLBN8aXR38uvOhHh3FhCOa8UxvbP+BoDjyO4z4+vUicHXLFvTGoyuh8gcfkKdP8aTDkGmAgM8ZP+yybh26LUFkKXpbA/Kq4A/IUHuaTzgOH0W3BUtvbMaWLBYaHDiEbovXDI8fLU4CX73pmd7Y/gNBceR3GMkjx0T6EdZRYjceXQm1f7lTtGaNJx2GTANE6uRZ8XmbNR3dliCyFL1jixdpMyBbbWut+21LBsrWvpui106RTLSc3f0HPNMb238gKI78DgO2RkQJmxHojUdXWqsUh9xfpZBtgMjcfyq2u4cOQLcliCxF74YB+Ra6vV4zdfqcsbo+Fd0WLL2xCTFxQa/IYjKxa7dYXV+5wjO9sf0HguLI7zCsEjY9gl0zU2Z6Gack2wDBS961d7/kHbF0vUM9OnkapyQTMw9DYsIxqC+6LVh6Y1KXmswmvU49RA4gwTEadxjWgMAaK3YD0o1en1SUcYCAwZivCDyqQ7claCymNzh9YsLXCd1WP8hP2Hf4kNfZhskHtj1+643N9PU7xg7TSHRb/KB1wr5/T8/0xvYfCIqjcYcBjZNvCd24g96AdKPXucpkHCDgsAs/eX7mArotQWMxvWHblw/I40ej2+oXIdyAr7DfD14VChnbdz6TBw+LmN9FC9Bt8YOvpPTyYMJBDiDBMRp3GNGF8wN9Uk5mpi9e9XzLQLYBIr6mRpw837Yd3ZagsZjeyf0HRYzS4kXotvrF6KwZgU11JWP7zqeObb1uSH8x4Xjw1BO9sf0HguJo3GEktmyl1BxItMoHLV/myfvLOEAkDx3RalXATxbTG1K/8AF55y50W/2imeoqvmkTui1+641NHVf74cCRuOfznuiN7T8QFEfjDiN18owYkGfPQG88ujG2aqWnA7KMAwSEGtDJc29YTG9I/swHp/OX0W31i8ljJ0T/Nnc2ui1+641NHeN94zWrRZ++Y6cnemP7DwTF0bjDgPqzPHB1+CD0xqMbI9MmiwH57EVP3l/GAcI6ed69A7otQWMxvSE4nQ/IT6PotvrFzO2HYsIxcii6LX7rjcmGE/8fanXiH3IA8l2dJYs90RvbfyAojsYdBhSEh8LwtZ1b81Op2A1IJ9YNFjNkSFfhxfvLOkCEenUxcoOl0G0JEpvTO5cy2nknvdo5nK7nE46u7dBt8VNvbEIMHF9YGNIf3RY/mb58XcR1Txjnid7Y/gNBcTTVYYT69RADciiO3oB04aspKj715BqyDhDh6rHi5PmVG+i2BInN6Z25Y6yEjRiMbqffbJhwBCsZsaztG5g6ZVT9mTkN3RY/6WVmB3IACY7RVIcRmTheDMiXrqE3IF2YfRIRM+SBvT27hqwDRGzpEnHyfJ83JZN0ZXN6wylYPiDPmYlup98Mjxsl+rdrwap+Imv7Blpl+DQ7XMhzu3ZuzVfbYXfNbb2x/QeC4miqw4gtW2oMyPvRG5AuTF8wssZPmeDZNWQdIBpKJq1EtyVIbE7vxJYtYkBevx7dTr8ZXbjAs3KLsuqNTavE5ZFj6Lb4zbphA0Vozz13c0+SA0hwjKY6DGtAXkUDsl9M7NkrnvmK5Z5dQ9YBIn3+snB+J3vn/OrI5vTWOd9nUFNdydq+geHRwz0rcSk7YdubH+47ddZ1vbH9B4LiaKrDSJ27JAbkqZPQG48uhILhPF3A7j2eXUPWAcKP7W8d2Zze1jbo9dvodvpNa/t7drC2v2Vt37ANCodueInLxDN0e/xmfM0aTxJgkwNIcIymOozs47BRNL0PeuPRheBs81kic769uoa0A4QPB2B0ZHN6Wwchohl0O/1mUA/AyNq+s+GUOAjRpxu6LRhMHjhkVNxZ6Lre2P4DQXE01WFYA3J7GpD9IjjbfEB+7F2SVFkHCH7/g/VLEus1C+ltpULp1h7dRgya91/bpW2gUuDI2r4bUqGMRbcF5f6v3BQTjuoxruuN7T8QFEehDqNucD9Pc9IRG8gd7vYfcnqZJFXWAQJoJcE+500SbB1ZSO8gJ0MulaHeXQOXe1LW9m2tgHmQDFkFZsNJT1ZAyQEkOEahDsOq23hWn7qNaB3E4zpfttxlHSCAcAKYx8ns2o1uS1BYSO/U8VNGCphZ6DZiMTx+tIiBvBqcVDCytu/4mhrRtrfvQLcFgzwVTJe2IgYy9cJVvbH9B4LiKNRheFnDkPgq/Tp0I+sAAUzs2SdWCZYvQ7clKCykd3yzvilgTEYXGalgDh5Gt8VrvbFpnYI9fQ7dFixCvCnfUbv7yFW9sf0HguIo1GEk9x/UetneT8LJX5EHb4Wn15F1gACmL16hVDA+6a1zChiTQUxMLGv7tvLg3Xc3D55KjM6eIZzgE6dd1RvbfyAojkIdBpTl0jlw109C7j++2rpnr6fXkXWAAFIqGP/0bkgBcwfdRiymTp4xUsHMQLfFa70x6WUlDJUIEw3ex2/Z6qre2P4DQXEU6jC8Clwlvk6o/sEH5AtXPL2OjAOESUoF45/eoV6dRTyShilgTMJWXNBSwcjYvrOhhGe1cFVi8tARMeFYuMBVvbH9B4LiKNRheBW4SnydsOrFTyQ+iXh6HRkHiFeeA6WC8Vxv3VPAWM+B9WlBSwUjY/umnSTjOVy7JSYc40a5qje2/0BQHM11GOGRQ0Tsxp2H6A0oqITVLlj1gtUvL1PAmB2GbANEPikVjPd6Z24/EAPRKH1TwJiE3Q0+4QgHIxWMjO1b9xQwJrORtJh49eriqt7Y/gNBcTTXYUCaCD4gHz+F3oCCSsizyGPfBvf1/FoyDhD5pFQw3uttpYCZOxvdPmxCYl6RCuYmui1e6Y1Nr8qgqUirHF7yuWt6Y/sPBMXRXIcR37BBnJTbvBm98QSVqbMXxRbJtMmeX0vGASKflArGe70pBUwDoTRXkFLByNi+KQVMAyHxOt9Ru/3ANb2x/QeC4miuw0gePS5WC+bPRW88QWVi5y7h9Kxa6fm1ZBwg8kmpYLzXO7pgnnB6jhxDtw+bViqYtWvQbfFKb2zWDR8knJ57+qaAMen2jho5gD6jqqoqw5guRmw77aC5DiNz856IFxozAr3xBJWw2sUH5L37Pb+WjANEPikVjPd6h8eOFNueN/RNAWMydfKsmODOmo5ui1d6Y5JSwLxKWHV3c0eNHECfUVFR8V9LIbaddtBch5GLPxOBq907ojeeoDIyuVoMyBeven4t2QaIxqRUMN7rTSlgGpi591hMOIYPQrfFK70xma1LUgqYPMKqO59wLJjnmt7Y/gNBcRTrMGjA8JZ1A3qJk4hPo55fS7YBosnnQalgPNM7lzAmdN06oNsmA3Opl3x1qrZzm0CkgpGtfVMKmEbP48YdsaM21p0dNXIAcfE7lZWV1Yx1jJ/BLyoqKv5HVVVVT2zD7KBYh0FVA7xjLvNJfW279+trO37seQoYs8OQaYBoipQKxju9M7fuGylghqHbJgthdYpPOOqS6La4rTc2rRQwixeh2yIDc7GsmID16OSa3tj+g7Zgzt585uwdYvwb5gD+EH7XqlWrb7Lv72PbZgfFOgyraPohfeuGesXMg1qxBTWkvy/Xk22AaIpwGIZSwXijN6WAeZ3h6rFignvlBrotbuuNTUoB8zpD3TuIHbV4zhW9sf0HbQGHPZgT+AfG95+YvzedQVVQrMMIYtF0WZg6c0FskUyf4sv1ZBsgmiKlgvFObwg+5215wwZ022QhrE7xCe6BQ+i2uK03NuFwDV/NP3UW3RZZGB49XJyKvnnPFb2x/QdtwRy9xNe+9rV/Dd+bDmCLFi3+iH0fRTXMJop1GNB4xUm54BRNl4WJHTuFs7N6lS/Xk22AaIqUCsY7vSkFzOuE1SnuFK9RPxWMbO2bUsC8zui8OaINHj3hit7Y/oO2YA7gEsaV4AQaDuBX2M+LGOdi22YHxTqMzP0ngTopJxNjS5eIzmDfAV+uJ9sA0RQpFYx3elMKmNcJCYr5BHfmNHRb3NYbkyIFTBuRAiZFKWBMxjduFBMO9tUNvbH9B23x5ptv/j5z9nYw5+9X7OvnjL+An996662vYttmB8U6jFz6E3FSrlPrQJyUk4mRiePFgHzpmi/Xk2mAKERKBeOd3qGexon+WBbdNlkIq1N8wjFsILotbuuNSUoB0zRh5Y9POObNcUVvbP9Be1RUVLzVsmXL77zzzjtfw7alHJTSYdT16ylOytXG0RtQkOj3c5VpgGj2uVAqGNf1bsjpSSlg8gkJikUqGPUnuDK17/SVm+LEeTWlgMmnVVxh9HBX9Mb2H7QGc/z+sLKy8gPGQfAVYgCxbbKLUjqMyKRqX1eqdCDGyqpMA0RzpFQw7utNKWAK00oFE0qg2+KW3ti2UAqYpunmRIwcQEQwh+9vGT9lvFlVVbWLfb0BPwepEohJP8uV6cLM/adi62noAN+uKdMA0RwpFYz7eqeOnaQUMAUYmTBOTHAvX0e3xS29sW2B+sqUAqZpQh5AN0IxyAFEBHP27jHHr3X+75jz93HQ8gACE7v2iNncypXojScoNIPPIz4Gn8s0QDRHSgXjvt7xTZuMFDDOg8+DxtiSxWKCu/8gui1u6Y1tC6WAKUyoBOLGYSxyABHBnL8fsS9fbvTrrxi/VwaldBip85eFszJ1EnrjCQoT23cY6SdqfLumTANEc6RUMO7rTSlgChOjLXqtN7YtDSlgHqPbIhvdaovkACKCOXrrIO6v0e/eY1yLZVM5KKXDaEjN0Qe98QSFGKsOMg0QzZFSwbivd8Oqw110u2Qjxmq813pj2kEpYJqnlZB9/XrHemP7D1qBOXybGDca5ClgGK8Z318zUsJsx7bTDkrpMCg1h/uEAul+xx3JMkAUI33e3NfbrbijIBIjHtdrvTHtyIaNFDB9uqE/ExlplWScM8ux3tj+g1aoqKgYUwqx7bSDUjsMqFfLl/QfhtAbUBCIcfJQlgGiFFIqGPf0fpagFDDNMSi5TmVp35QCpnlmbj8Qz2fkUMd6Y/sPBMVRaocRmT5VBPWeuYDegFQnVu4xWQaIUkipYNzTO3P7vmu5x4LKUL8exoRM3VynsrTv5MHDRgqYhejPREbmks/FhKxrO8d6Y/sPWqNFixa/W1FR8ZeVlZV/z77+g0lsu+yg1A4jXlMjjvXv2InegFSnVX3A5/J6sgwQpZBSwbind+qYe9UHgsrIRPVTwcjSvikFTHGGenURE45I2pHe2P6DtjDyAOagDjD7+hv4yvhrxjC2bXZQaodhJfZcshi98ahOSI3AB+RZ0329riwDRCmkVDDu6Z3YTClgitGqy73fn7rcXuqN3b6js2aI1fuTlAKmEMPjRokJx7VbjvTG9h+0BXP0rjPHrzd8Dwmgja8jGAfiWmYPpXYYFNfhHmFmzAdkNlP287qyDBClkFLBuKd3bP5c4dwcPY5uk6yEnQ3eJmtWo9viVG/s9k0pYIozunCBaJOHjjjSG9t/0Bb5eQBNB5Dhd9jvU3hW2UepHUY2nKKTXS4RYmN44z942NfryjJAlEJKBeOe3uExIgUM1CHFtklWps6cFxOO6VPRbXGqN2b75ilgurSlFDBFmNiyVUw41q1zpDe2/6AtmNMX+9a3vvVvjO8fVlRU/Mdvf/vbf8K+/wzbNjsotcPgDbtrO5FKIvkcvQGpzHD1GLH8f/Wmr9eVYYAolSIVzEeUCsYFvUM9KQVMMWYeqJ8KRob2TSlgSmPqxGkRBjR7hiO9sf0HbVFVVTWTOXvvG98PYHzBmGFcjm2bHdjpMODYOl9JuP0QvQGpTOgceQAw6yz9vK4MA4Qd1g3uR6lgHOr9+c9+aqSA6Yhuj8zMZT5hk43362s7fqxsKhgZ2jdMakWo0Bj05yEzM3cfiec0YrAjvbH9B4IB5vj9TatWrf7xS6+Xh5MadjoMKCTPg3uPn0JvQKoyl3rBnyFsk/g90MgwQNghpYJxrvfPI2FKAVMi6/r3FBOO2hi6LeXqjd2+KQVMaXRjHCAHkOAYdjoMOEXI4xY2bUJvQKrSjZlfuZRhgLBDSgXjXO8fXblIKWBKZGRStQjNuHQN3ZZy9cZu3/G1a0Wb3boN/XnITqc7QeQA+ozKyspLjBeLEdtOO7DTYSSPUj4xp0ydPOM49qNcyjBA2CGlgnGu98s9xunWjZQCphhjy4xUMPvUTAUjQ/uGfo1SwJRGKxb8Snmx4OQA+oyqqqo2pRDbTjuw02FkblFFAaeEmbHT01/lUoYBwg4pFYxzvbPLjBPnbPKGbY/sTOzcJSYcq1eh21Ku3tjtG3Y2eJz43Ufoz0N2WtkgDhwqW29s/4GgOOx0GDmzpmg3qilaLqOLnOd/KpcyDBB2SKlgnOudmDCaUsCUyNTZC0YqmCnotpSrN2b7phQw9mjlg11TU7be2P4DQXHY7TDcKGGjM8PjRzvOAF8usQcIu6RUMM71DvfqLFLAxHPo9sjOzMOQmHAM6Y9uS7l6Y7ZvyhVrj6nT58SEY+a0svXG9h8IisNuh4HpwASBod54DjT2AFEOKRWMAyZyYkDuQSlgSuErqWDY5APbHrvEbt/pq7coBYwNOs09SQ4gwTHsdhixRThVLIJASKDNj/53bYdyfewBohxSKpjymbl1TwzIYyhmt1TWDeglJhxPo+i22CV2+7ZSwCyiFDCl0OmEgxxARFRUVLyFbYMbsNthNNSxXYvegFRj5s5DMSCPHIJyfewBohxSKpjymTpmnNqfT6f2S2VkspEK5uJVdFvsErt9w8E2SgFjj04mHOQAIqKysvIXjHsZ/4X9+NteXos5m0PYdf6ZsZp9/w2nr8uH3Q7DjFuIzpqO3nhUo1X+Z85MlOtjDxDlkFLBOHh2m0TezgTl7SyZ8DnjOxx796PbYpfY7bshBcwZ9GehCiNTJhgTjitl6e2el0GwhRYtWvwxc7QGVlVV3THKwC1s2bLld9y+DnPkvmuWl2Nfv86uucPJ6xrDboeRuW/ELQwbiN54VKMbBcCdEHuAKIeUCqZ8wsofH5CPUQqYUmmlglmlXioY7PZNKWDsM7ZiuZik7dlblt7ueRqEssGcr79kTtcsxjRzvB7CSpxbW8TsPYez9+po/szeP+HkdY1ht8PIpdWvmYnFhhQwq/CfOAAAIABJREFUR1Gujz1AlENKBVM+IfaPD8i3KAVMqUydFZVTIPYU2xa7xGzfVgoYOHGeeoH+LFQhOH58wsEcwXL0du5hEBzjnXfe+d+ZAzaTMcN4HVbfGD9jDll3p+/N3mce4/t5P8ffeuutr5b7usaADuPFC/FhKpVm3EIuFLP1/3RnxDhBnbl+C+X6oHM5emPyWa4hFcyz7Kfo9qhEOP0Ln7fnyRy6Laow+6ghFQy2LXaJ2b5z0YYUMNjPQSVaOxxTJpSlt1P/glAmmNP3Nebg9YctYOZsZcEBbNmy5Z+bf2e/+/eMP3R6HdhaZtd5N+/n9Ntvv/175b6uMerLQGrmFP6h/enD++X8d20R6SdqP/7mxz/CNkUpxIYP4M/tV7kstinK4Dc//ak4cNSrM7YpSuGL3/ymvrb9B/Whjh/Vf/H559jmKIOf1T4RuxtTxmObohR+/fKFiAsf3Kes/+/UvyCUCebc/Zw5WbtbtWr1PfbjbzX1Gvb3FU6vY2ztts/7OeXkdY0BHyK7M8a4EbeQ3LsPfQalCp+lRAqYEE8B8xmKDSquAALNVDDp8xfRbVGFZgoYqASimt7YtHY4aqPottghZvtOHT4itjIXL0R/DiqR73B0/JiHVT3LfmJbb6f+BaFMwAqgH9dhjtxfweoefN+yZctKOHkM3zNnr1UprysG6DD4B9FO3MJuI25h5Qr0GApVCIHRmClgzJiRcvTGJqWCsc/k0eMivcTyRcrpjU1VU8Fgtm9KAVM+IRE0Dw168NS23m77GwQJwZy9Scy5e49xSqtWrSrYr95gDl6I/f4PiryuKMrpMNIXzLiFieiNRxVaKWBm46SAMTsMFR1ASgVjn/GNIgXMyz07ldMbm6qmgsFs39CvUQqYMp/dzGni2Z0+Z1tvTxwOgj4op8Ogk5n2CTNjzBQwZoehogNIqWDsMzpPpID50ZWLyumNTVhpVjEVDGb7phQw5TO+do1YPd223bbe2P4DQXGU02FA2RrzZCaUs8FuQCqwIQXMETQbVHUAIUs+n3AM6IVuiyoMjxYpYH4RDSunNzZVTQWD1b55Cpiu7SgFTJm0SugttldCjxxAgmOU22FAmgQRt1CL3oBUYNhIAZO+dgvNBlUdwFcnHJ+i26MCQ91FCpjPf/Yz5fTGZuZhQyoYbFvsEKt9ZyNGCpjeXdGfgYpMX70l4sPZGGFXb2z/QWtUVFR0qKqqOsF4F36urKz82/xULCqg3A4jMmOqiFs4cx69AalA6Bx5UD7rLLFsUNUBBNYN7icmHGxwxrZFduZiWTEg9+ykrN6oz49NMmCyAZMOmHxg21Mqsdp3uQ4MUTAbSRsOdBfbemP7D9qCOXpjmMN3g339yMz3Bwcv4HfYttlBuR1GfE1NWXELOhK2ReBZwTYJZvUUlR1AMxUMbM9h2yI70zfuigF57Ahl9cammQoGwg+wbSmVWO3b2sJcZG8Lk9jAULf2Ygs98cyW3tj+g7Zgjl4M6gEb339q/PqNvO+VQLkdRvLAISNuYRF645GdVgqYEYNR7VDZAYSAfD7h2LkL3RbZaaaAic2fq6ze2FQxFQxW+46vXUspYBwyPGqYUbbxvi29sf0HbQHVP9iX34bvq6qqPoGvUHmj1ATMsqDcDiN95YZwaqrHojce2QmpEbBTwJgdhqoOQXLffuHULFuKbovsjG8QKWASmzcpqzc2VUwFg9W+o7NmGClgzqI/A1VpntpPHjthS29s/0FbMEdvM3MCxxvfcweQ/TyyoqJiDa5l9lBuh5GtS1q1H7Ebj+yUIQWM2WGo6hDASoxIBVONbovsjM6dLQbk4yeV1RubKqaCwWrfdcMHidWre4/Rn4GqjG/aJMaIjRtt6Y3tP2gLqATCHL4rsOLH+GvGMPzcqlWrf4dtmx2U22Hwo/+d29TXtn2vPpd6id6AZCbExvDZ3cHDqHao7ABSKpjSaaaAydy+r6ze2FQxFQxG+6ZxwB2mjp0Uu0Rs8mZHb2z/QXe8ASXYKioqvs+cv//Cfv4ytkF24aTDsGZ+lPyzWVopYK7ipYAxOwxVHQKeCsaomUm5J5tnqHsH/nl7lnimrN7YVDEVDEb7pp0gd5i5/UCEVI0aaktvbP+BoDicdBgNsR9U/qc5QufITxSG8VLAmB2Gyg4B5Z4szoYUMJ2V1xv1OSqYCgZD7/SVmxQL7gJzyee2M0WQA4iIioqK/1BZWXmE8Rnjzwz+HL5i22YHTjoMOv1VQsM2U8B0aYuaAsbsMFR2CCLTpxi5Jy+g2yIr81PAqK43NlVLBYOhN2WDcI92c8WSA4iIqqqqO8zZm8scwe+y7/8in9i22YGTDsPM/wRlzrAbj6yUJQWM2WGo7BDEVlMqmGJMHjkm2uSCecrrjU3VUsFg6B1fU14dW+LrDFePMUKFbpasN7b/oC2Y8/cZ+/IGth1O4aTDoAzwxdmQAmYGui2qOwTJfQeMVDBL0G2RlfENG8Rpws2bldcbm6qlgsHQOzpzmliVP30O/f5VJ6yi8s/bgUMl643tP2gLSPfCnMC/x7bDKZx0GA01IO2VsNGJVgqYtWvRbVHdIUhfuiZOZk4cj26LrLRSwBw7qbze2FQtFQyG3nXDBoq43PtP0O9fdSa27xBjxZqakvXG9h+0RYsWLf6oqqrqMeNB5giuyie2bXbgpMPgKQC6thMlbJLP0RuQjJQlBYzZYajsEGRr4+JkZr+e6LbIyvyKAqrrjU3VUsH4rTfv/zu1Filg0nQy3ylTZ86Lz9uMqSXrje0/aAvm6G1nzt8TiANkXyfnE9s2O3DaYYRHDjFyjj1Eb0Ay0m5ch5dU3SHgAw6kgqEBpyBD3TpYNUVV1xubViqYwf3QbSmFfuudDYkJWahfD/R7DwIhu4Gd1EPkACKCOXo/+da3vvVvsO1wCqcdRnTOTKPqwCn0BiQjZUkBY3YYqjsEdUMHGKlgnqLbIhtz0YyVAiYoeqM+T8VSwfitd/rydbFiNWEc+r0HgZDf1M7njRxARFRWVt5o0aLFH2Pb4RROO4z4+vVG0PkW9AYkG2VKAWN2GKo7BLA9IlLBnEe3RTamb9wxUsCMDIze2FQpFYzfeif3G4eylixGv/egsG5gb/F5exIpSW9s/0FbMAdwYFVV1TXG1hUVFf+QT2zb7MBph5E8fNRKO4HdeGSjTClgzA5DdYcgXlMj0k7s2Ilui2zMTwETFL2xqVIqGL/1prboPiNTJorP2/nLJemN7T9oC+b4RQowjG2bHTjtMNLXX111IDYwdfKsGJBn4aeAMTsM1R0CWnUozPwUMEHRG5sqpYLxW29ajXefsZUrhFO9e09JemP7DwTF4bTDaBx3RGygTClgzA5DdYfAijuaSHFHjWmlgDHicYOgNzZVSgXjt94Uj+s+E3v2ic8bm3iUoje2/6A9vv3tb7/TsmXLv27BgG1LOXCjw7BOHsafoTcgmRhbLE8KGLPDUN0hoJOHhQmF5MWJ/AeB0RubKqWC8VNv60R+u/f54QXsew8KIdSAf94mV5ekN7b/oC2Y4/cnVVVV5xh/xZgxvp7/5je/+Ta2bXbgRoeRn3sMuwHJRJlSwJgdhuoOAeUeK8z8FDBB0RubKqWC8VPvbG1MPJf+lJMT67mSA4iIysrKnYyL3nrrra/Cz/CVOYALGXdj22YHbnQY5tZT8tgJ9AYkExtSwCTRbTE7jCA4BNbWE1UfsGiFYvRqCMUIit6oz1WhVDB+6m1V5ZlUfKWKWDrt5DolBxARzNF7XlFR8a/yf9eiRYvfZb9/gWVTOXCjw4hv2Chi3TZtQm9AsjCXeskbsSwpYMwOIwgOQYTqj75G6zDWuFGB0xubqqSC8VPv5L79VJfbIzaU12s+tpIcQERUVlbWtWzZsjL/d/CzbqeAeWdw9Lg47TpvDnrjkYWZe4/FUv7wQei25HcYQXAIoFYmPym3fQe6LbKwcQqYIOmNTVVSwfipNxyK4W1w5y70+w4ao7OmlzTBJQcQEcwBHAzOHvvaq6Ki4v+Fr+AUsu+HYNtmB250GJmb98Tqw+jh6I1HFsqWAsbsMILgECQPHKJUMI3YVEL2oOiNTVVSwfipNxyK4U7K2Qvo9x00QtYI7lxv215Ub2z/QWswh68t4zHGh8bXtuzXb2DbZQdudBi5eE7EH3XviN54ZCE0XpECZg26LfkdRhAcgoYSVGPRbZGF0TmzXivJGBS9salKKhg/9YZ6tXyb8mEI/b6DxuShI+LztmhhUb2x/QeC4nCrwwj16ChOIMay6A1IBsqWAsbsMILgEGRDCTHh6Nsd3RZZ2DgFTJD0xqYqqWD80hsOw8ChGDgcA4dksO87aExfvy121MaPLqo3tv+gLSoqKt5t0aLFn8H3LVu2rKqsrDxTVVV1Er7Hts0O3OowwmNGiDiZG3fRG5AMDFePFc/jihwpYMwOIwgOAT8p19lMBfMS3R4ZGOrWXkzAks8Dpzc2VUkF45fecBiGP48BvdDvOYjMWif6uxTVG9t/0BbM4Qu98847XzO+38c4lzmFE5kTeBzbNjtwq8OIzp8rVryOHENvQDJQthQwZocRFIcADtfwFa97lAqm0IARJL0xqUoqGL/0Tl+8YiQrnoB+z0FlqPurOT0L6Y3tP2gL5uj9CL5C6hfm/H0GX9mPX2G//wTZNFtwq8OAFDA85m3DBvTGg00rBUznNtKkgDE7jKA4BFEzFcyps+i2YLOpFDBB0xubKqSC8UtvO+XKiOURDlQWK65ADiAimNMXb9WqVQVz+P6JfX8afgd5AcEZRDbNFtzqMFLHTopTr3NnozcebMqYAsbsMILiEMTXrCnppJwOTB4+KtrewvmB1RubKqSC8Uvv2MqVou3t2o1+z0ElpFTjO2pHCxdXIAcQEczRG8j4UyBz/P4/+F3Lli3/b/bzZWzb7MCtDgNmKnwVYtRQ9MaDTViVEilgpqPb0rjDCIpDYKWCWbwI3RZsmilgElu2vPL7IOmNTRVSwfild2TqJLH6fu4i+j0HlQ07ahub1Rvbf9AacOCDoWX+z4x/jmmTXbjVYUCsAo9D6tYevfFgU8YUMGaHERSHAA7X8AlHNaWCaSoFTND0xmZDKpiV6LYUol961w3qK7bDH9Wh33NQCW252I4aOYAEx3Czw4A6pLxjiGbQGxAmYVWKrxYcOIRuS+MOIygOARyu4ROOPt3QbcFmeKSZAuZhYPXGpgqpYPzQm6eAaf8hI6WA8ZLQlvkEd2ThHTVyAAmO4WaHAUHoPE7m+m30BoRJGVPAmB1GUBwCkQqmjUgFk9I7FUyoa7vXUsAETW9sqpAKxg+9s08i4jkM7IN+v0EmtGV4zrWsbRc6SEgOIMEx3OwwIAidr3wdOoregDAJCYr5SmidPClgzA4jSA5BQyqYx+i2YLG5nGFB0xuTKqSC8UPv9PnLYiV0ykT0+w06G1KJpQrqje0/EBSHmx0GBKHz2Ld169AbDxZlTQFjdhhBcgigzjKPfTupbyoYq2pAoxQwQdQbm7KngvFD78TuvSIWcsVy9PsNOovtJJEDSHAMNzuM1InTInB19kz0xoNFSEwsYwoYs8MIkkNgFU3fug3dFizCartIAbMg8HpjU/ZUMH7oDY4fb3PMEcS+36AztmRxs7Hk5AASHMPNDiNzxwhcHTEYvfFgUdYUMGaHESSHAOosl1I0PcgslAImiHpjU/ZUMH7oDVu/fNX9/GX0+w06Ezt2ih21mpqCemP7DwTF4WaHYQWudmkr3fanb43WTAGzRq4UMGaHESSHIH31ZklF04PM6JyZYkA+cTrwemNT9lQwfugNhz/4NvjjMPr9Bp2pMxdEvOX0qQX1xvYfCIrD7Q4j1Ltrs4GrQaesKWDMDiNIDgF8xnRPBRMeOUQchLnz8LW/BU1vbMqeCsZrvflBmPYf8DQwsh6ECRKtk+dD+hfUG9t/ICgOtzsMWI3hcTJX5UqB4hcbAndvoNvSVIcRJIeAp4Lp0lakQEm9QLcHg4VSwARRb2zKngrGa70h8TO//0F90e9VBzacPG/a4SYHkOAYbncYEI/FV8AOHkZvQBi0VkAj8q2ABtEhgHhTvgJ29xG6LX4zG0mLFdDer6eACaremJQ9FYzXekPpN74COnUS+r3qQmvL/UmkSb2x/QeC4nC7w4ATmTKWQfODubhZDq8Dui1NMYgOQXT2jIIxcEFn+tqtZmMgg6g3NmVOBeO13olde0QM5Eo5YyCDSKvuchOHbsgBJDiG2x0G5GST9RSs18zcvCcG5DEj0G1pikF0CCDnpK6pYJpLARNUvbEZmTxBhHhcuIJui996m6egE3v2od+rLgRnmz9z5nw3pTe2/0BQHG53GFCVQdY8eF4zedgckOej29IUg+gQJA8dEc98UdNOUJBpOb9btmqjNzZjK1cUHJCx6bXelvN7UT7nN6iElEN81ZU5303pje0/EBSH2x1GQyWM1tqlgpE9MXEQHYL01ea3QYNMSLje3PZ3EPXGZnKfMSAvW4Jui996W9vfTcSjEb1h+tI1EXc5qbpJvbH9B4Li8KLDsGrhhhLoDchPRmZOEwPy6XPotjTFIDoEcNimuYMQQaZVC7nAAZgg6o3N9OXrYkCeMBbdFj/1lv0ATFCZrY2LHbV+PZvUG9t/ICgOLzoM6Bz5VgHrLLEbkJ+EfE18QH5Qi25LUwyiQ8BTwTSTCiWohEG4tuPHfLU9l36pjd7YlHnC4aXesqfACSp5/9apdZPtnBxAgmN40WFYNQz3H0RvQL41VBiQ23/IE6XCbBnbnqYYVIfASoZ8+/VkyEElbMPxAXlAL+30xiac8ucTjvgzdFv80jt19oLUSbCDTGul/96T1/TG9h8IisOLDiOxfUezNQyDyIYZsrxJUoPqEETnzBJb78dOotviF1PnLhXNyRZUvbEJp/z5DseNu+i2+KV3YucuowzeKvT71I3RWUaqq5NnX9Mb238gKA4vOgyIgeOD04ymaxgGkakz55ut2ygDg+oQxDdtEhOODRvQbfGLZqH42OrCA3JQ9cYmpN3hOxyHjqLb4pfesWVLxT3v249+n7qxUKorcgAJjuFFh5G5/1Sshg0dgN54/GJi23bhhKyRNwF2UB0COAXLU8HMnoFui1+MLV5YtOZ0UPXGpqxt3Uu9IxPHi1XPS9fQ71M3Fsr3SQ4gwTG86DBy6U9EKpiOH2uTCqZhVeAIui2FGFSHAGJjdJtwhMeNEgPytVva6Y1NWVf7vdQ71KeblpkdZGD6+h2R6oq1+cZ6Y/sPBMXhVYcBx9Z5h1EbQ29AfjA81owLuoNuSyEG1SHIZT7RLkVFqEdHcRAhltVOb2zKGu/rld65hChxCaftdZnQy8RcNCNOnvfs/Jre2P4DQXF4tmUwqVqrrPGh7ubJwBy6LYUYZIegbpBRNP1RHbotXjNbYEDQSW9M8hP/HeQ78e+V3laJy9HD0e9RV4a6d3xtfCEHkOAYngUNr1gubckkt2nlBuslX26wfAbZIYhMnyJOyp05j26L10xfvVlS9ZMg643NhpyfT9Ft8Vpvq9yipCUudaB58hyc8Xy9sf0HguLwaoBI7jsgTikula9kkttMXzEG5Oox6LY0xyA7BBCQL3MZPjcJ+TV521qyWFu9sRk1q/6cOotui9d6x9fUiLa1bTv6PerK6IJ5Isb86PFX9Mb2HwiKw6sBwnKKNKjRWuqAjM0gOwTWSTnWUWLb4jVjq1aKAXnnLm31xqaVmmPLVnRbvNYbkj+L1fUL6PeoK+Obt7yW6oocQIJjeDVAWHFKPTqhNx6vCclRSxmQsRlkh0CnOKXIlAliQD5/WVu9sZk8cky6CYdXetcN7C3iax+H0e9RV1qprubMekVvbP+BoDi8HCAgSJ13HMwZxG5AXhKqMZQyIGMzyA4B1AHW5aRiXX/jhP3TqLZ6YzNz676YcIwahm6Ll3rzlF7t3hcpvTQ5YS8jM3cfic/byCGv6I3tPxAUh5cDBMTE8ZPAV26iNyAvCfVYSxmQsRl0h0CHXGW51EuRY7Nz66KObtD1RtVBwgmHF3qbjgfUo8W+P52ZS70Q7b5LW+vzRg4gwTG8HCDgAEjQywfl0i/FDLlTa+lnyEF3CKxqBRevotviFTN3HoqVgBGDtdcbm6G+3cWEoy6JbotXeqeOn3pt65GIQ2uCG05aemP7DwTF4eUAkdi9RxyOWLEcvfF4xcy9x8rMkIPuEFiph3YHN/VQ8tgJMSDPna293tiUrTyaF3rDoQN++GDTJvT7052RCWONHbUblt7Y/gNBcXg5QEDHyEsmsY4Su/F4xYbg3JnothRj0B2C5N79YsKxLLiph+Lr15c8IAddb2zGli8TE449e9Ft8UpvqK/N45tZP4d9f7oTskzwHbX9By29sf0HguLwcoCArRF+ErhPN/TG4xVhIBbH8zei21KMQXcI0pevG/kYx6Lb4hXtDMhB1xub4PjxCQdzBLFt8UpvqK/NExDff4J+f7ozsWOnGGtqVlt6Y/sPBMXh5QABwaqhbu2NEjbP0BuQF4StOD4gHzuJbksxBt0hsCqy9Ja7IosT2hmQg643NmXb4XBbb6vkXbsPeL1t7PvTnamzF8TnbfoUS29s/4GgOLweIMJjRQmb9I076A3Ik/sbOUQMyHceottSjDo4BCrUZC6XYkD+qOQBWQe9MSnbDofbemcehkR886C+6PdGzNNjcD9Lb2z/gaA4vB4gYosWiriFg4fRG5DbhBXO2s5t+PF8OKaPbU8x6uAQhMeOFBOO68GbcGQf1xkDch/SWwLy9t+1nZhwJJ+j2+O23qnT58SK04yp6PdGZJ+3zKf1te0/4KuyMBkkB5DgGF4PEGbcQmz1KvQG5DaztXGxAtCvB7otpVAHhyDIEw4oxcUH5GmTSW9JCImg+Q7ArfvotritN5S54zFna9ei3xtRECZ/ZlUWcgAJjuH1AJE6d0kMWlMmojcet5m+eEXc2+RqdFtKoQ4OQWL7jlcCpYPExLbt4t7W1JDekhBKwfEJx5Fj6La4rXd0/lxp7o0oaFWdYuMqOYAEx/B6gIDqGHzbqn9P9MbjNlXLc6iDQ5A6e1E45ayjxLbFbUYXLhAD8qEjpLcktFbJ1q1Dt8VtvcOjhkqzukkUjK1aKVIP7dpNDiDBObweIFSLk7PVGJctFQPyXjUqnejgEGSfRMSEY0AvdFvcpt0DVTrojc3UqbMiD+jMaei2uKl3kPttlQlVtUSu06XkABKcw48BIjwymDPJyIRxYkC+fB3dllKog0PAT8p2/FgMXOmX6Pa4yVA384RzaSmVdNAbm5kHtWLCMaQ/ui1u6p2tjSkV36wL81MPkQNIcAw/BoigxpI0rs0oO3VxCKAsH59w3H2EbotbzIbNHIddSW+J2PhkJqYtbuqdPn/ZiN2egP6MiQ3MhhoOHpIDSHAMPwaIIJ4myyWeiYbYtR3fLsG2pxTq4hBA4XpVknOXSrPKCdQDJb3lYt3gvmLC8TCEaoebeid27hJbjatWoj9fYgPF1nxrvsPxLPOSHECCM/gxQFj5pKYHJ59U5uY9UXZs9HB0W0qlLg5BQ3m+Dei2uMWGOsdLSW/JCP0an3CcOY9qh5t6xxYveqXuLFEemjsc2XuPyQEMOioqKoZUVlb+M2M1+/4bzb22qqrqL9iXr7z11ltfbdWqVUUp7+/HAJF9ZCawDU5GedjO5sHfC+ah21IqdXEIoE4u12b2DHRb3CKcNOen/3bvIb0lY3ztGqHNtu2odripd3jcKBHffPUW+vMlvkqrHvipM+QABhnM4fsuc+qWw/fs69eZE7ijudezv99ir3vBuOvtt99+s5Rr+DFAWIH5UMIqHYyakpD2gXf6W7ai21IqdXEIMveeiAnH0AHotrjFyKRqMSBfvEp6S8bkoaNiwrFwAaodbuod6tFRHDiKZdGfL/FVWmPP1q3kAAYZzJEbzpzAjubPzMFLFHl9a7vX8GuAqBs2UMTJ3HuM3oDcYHTWdGMWdhbdllKpi0MAdXJhsgF1c7ED891iqG93se0TSpDekjF9464IBxkzAtUOt/TORtIivrlXZ/RnS3ydycNiwhFbOJ8cwCCDOXzzGN/P+zkO27uFXs8cwCmtWrX6R/Z1WIsWLf6slGtAh/Hiheg8vGR0zkzhMB0/5fm1/CCsLvEB+eFTdFtKJejsl97YbCiZVIdui1M+Sz3n91LbpS0bAD4jvSXjM/NAWLcOqHa4pXfm6g0Rs109Bv3ZEpvQ58Ydoc+4keQABhnMkVtYUVHxbt7P6bfffvv3mvkvb8A/b7755u8zZ/FSKdeo9wkv94iawC93b/frkp7hi88/rw91/Iinf/ji17/GNofQBNLzRJzMT27dwDbFMX4RDYtDLeNHYptCKIBIP5ES6jc/+gzbFMf44anj/F6erV2FbQqhCfzmJz8RK869OpMDqDqYU/c34KwxXmzEHbCSxxzA9nmvTRV6n1atWn2P/X2m8eOX2f//aSnXhw+UHysEqZMNgfnYMyinhFUl81ALti12qNOKUENg/jZ0W5wydVQcOIrNn0t6S0pIz8NDXK7eQLPBLb3jxoGj5O496M+V2DTNGM3r3//+Hzp0QQiygjl0fwWrgPB9y5YtmU9Xudf8G3MMW+W/ljmAf8de8x34/p133vlT9tqjpVwDOgz4QHkdt5C5H5zA/NTZC0Zamynottgh6OyX3ti0AvMVOqVdiOUeONJJb2zGli0RTtM+vLKQbukNVSbsHjgi+kuzLOTjj//lP7vpcxAkA3P0JjEn8D0jvs9M7fIGc/BC7G9/0Oi1HWHFkP1tvEyngIE8MF+SjPlOmdi+Q2zJralBt8UOdXIIVMzTWIiRmdNE/Ozpc6S3pIT0PHyVduUKNBvc0tuqcFSnRoUjHQkTW9Doaevvf+C600HQB34OELJkzHfK2KKFYrZ/8DC6LXaok0OQSz5XrlJLIUKdWd5uHtTh1AiHAAAf1klEQVSS3pIyffGK2BWYjFc6zQ29VaxwpCMTW7ZwnZ60fncstg9BUBh+DhDWSoZCqVOaopUk9foddFvsUDeHIAgrGaLW7Iec8D3pLSeztaJGa12/nmg2uKG3ldImACvnQaaZ7P5p63c3YvsQBIXh5wDREMu0Bb0BOaGqSVJ1cwisWKZL19BtKZewWs4di8H9SG+JKWq0tuE1WnOpFyg2uKF38tARKZJaE5tn5u4jkRqqzbvXsX0IgsLwc4BIHj0hOpd5c9AbULnMRjPKJknVzSFoKJ+2F92WcmnV0Z45jfSWnOGRQ8VW/e2HKNd3Q+94TY0UZe2IzTOXesknG0/bvPsM24cgKAw/BwjoGPn2wojB6A2oXEJtTH4P40ej22KXujkEyb37RWD+sqXotpRLOPnLDxytW0d6S06Y2PLY4GMnUK7vht6RaZNFmM7ZC+jPk9g8kzt31j9p/f3+2D4EQWH4OUCYs5baTq2VPQmcPHBIOBWLF6HbYpe6OQTpy9fF6tmEsei2lEvztF/yyDHSW3LGN28Wzvr69SjXd0PvuoG9Rdzskwj68yQW1xvbfyAoDr8HiLoBvZTuYKxtxZ270G0pp8PQySHIRlJiu753F3RbymV41DCxrXjrPuktOc3AfEh2j3F9p3rn0sYEvePHyk7QdSI5gATH8HuAiEydZGwxXERvQOUQtn75wYIrN9BtKafD0M0hgPqs/MBOPIdui13ygwVd2wn7k89Jb8lpJbsfNhDl+k71Ng8W1A0fhP4siaXpje0/EBSH3wOEykHGfEDu0lac9Is/Q7ennA5DN4fAzJivWsoeYDaUECuYfbuT3gqQJ7tvB8nuP0JZQXOqd+rYSbGCOXc2+rMklqY3tv9AUBx+DxAqpxnIPjJqAA/sjW5LuR2Gbg5BdNECJZN2A6EUF49hnFRNeitCK2n3/ae+X9up3vENG0QM46ZN6M+RWJre2P4DQXH4PUCoXKIrdfyUcF5n4cT4uNFh6OYQWGX7alaj22Lb9t17xYGjFctJb0UYnTNThLgcO+n7tZ3qDf0at/3EafTnSCxNb2z/gaA4/B4gzBJdtQqWGoqvWWMkst6Kbku5HYZuDgHEmvJVtKmT0G2xy9iSxWL1ct8B0lsRWml71q7x/dpO9a4bOsBYvXyC/hyJpemN7T8QFAfGAAExTfwkcCiB3ojsMDK5WsyQz19Gt6XcDkM3hwBOm/Nt+wG90G2xS1gl5/GLN8qLX9RRb2ymzhkTjikTfb+2E70hZrG2A5Qc/IDHMmI/R2JpemP7DwTFgTFAmI4UFFDHbkR2GOrZWTiukRS6LeV2GLo5BHxg69watURX2XZ3cma3jnpj0zq406eb79d2ondDycG+6M+QWLre2P4DQXFgDBCxlSvEVuqu3eiNqFRmQ3G0jt3NDkNHh8DpShoGrQF5UPkDsq56YxLCWkLdjVrh0Yyv13ait1VycMZU9GdILF1vbP+BoDgwBojk/gMiuH3JYvRGVCpTZy4oG0uW32Ho6BA0xNLtR7elVFoHjhwkFdZVb2xC5Rk+4bh0zdfrOtE7sWWLEbu4Fv35EUvXG9t/ICgOjAFCxXq68Y0bUcs8udVh6OgQgOOn2oQDBmJx4GgL6a0YYytXolQLcqI3TDR4fDObeGA/P2LpemP7DwTFgTFA5GJZsZ3avSN6IyqVkelTRQd56iy6LU46DB0dAtj6VS31kBsVc3TVG5uQc1LkOp3v63Wd6F03sI84AfwwhP78iKXrje0/EBQH1gAR6t3VOAkcR29IJdlrnlx+GkW3xUmHoaNDAIcoeI3TTq2VqXEKsaZO24euemMzc/uBmHCMGOzrdcvVO5d4JtpH5zbKtA8iOYAEF4A1QFgrHGcuoDekYoRgbrFi2UG53IWNOwxdHQI43chXOB7UottSjFnz89ajo6PPm856YzKXzisJl/nUt+uWq7cVkjN2JPqzI9rTG9t/ICgOrAECYulUKTtkleSaMA7dFqcdhq4OAWaFBrt06/Oms97YbCgJ519S5XL1TuzeI2Jkly9Df25Ee3pj+w8ExYE1QKROnhWD3HT50w4ktm1XtpxY4w5DV4cgsXWb0HCN/xUabNu6Y6cYkFetJL0VZXTubHHy/OgJ365Zrt5Ql53beuAQ+nMj2tMb238gKA6sAQJi6fg2V78e6A2pGKNzZvnemXvVYejqEED1Fj7hmDwB3ZZijM6fKz5vh4+S3oqyYcJR49s1y9UbYhX5auWt++jPjWhPb2z/gaA4sAYInjC1WweUhKl2Ccl4RfzYU3RbnHYYujoE2XBSTDh6dUG3pRjrhg0Un7e7j0hvRZk6d8koCeffhKMcvaHsW217owRcmkrAqURyAAmOgTlAQIyTKAl3Fb0xFWIu+dw4IafOCdLmOgydHQJw/vjJWuYMYttSiA0D8oeOa7Lqrjcms3XGhKN3V9+uWY7emTsPRcWZ4YPQnxnRvt7Y/gNBcWAOELHVq0TC1G3b0RtTITackBuBbosbHYbODgFs//KDIOcvo9tSiG4OyLrrjc1Qj05iwuHTDkc5els5CxfMQ39eRPt6Y/sPBMWBOUBATB3vfObMQm9MhRikE3K6OwRwAIRPOLZuQ7elEJOHjrg2IOuuNzatHQ6fSsKVo3dsxXKUqiVEd/TG9h8IigNzgICYOqcF771mkE7I6e4QQAoYMeGYiW5LIVplxHbsJL0VJ5zidktLr/QOjxslnNQrN9CfF9G+3tj+A0FxYA4QEFMHsXUQYwexdtgNqinCVhwPyL/9EN0WNzoMnR0CSALNJxyD5Z1wRCaMdW3VSHe9sZk8dNTX7VW7esNBvNoubcVBvPgz9OdFtK83tv9AUBzYAwTE1vEB7+ot9AbVmDyjPwTkd3AekC8DdXcI+ISjkzHhSL1At+c1++BkfHf3Tsbrrjc2YdLo5wELu3pnH9cJ+wb0Qn9WxPL0xvYfCIoDe4CILVsqtkl270FvUI0JebEwanp62WFg643N8OjhYsJx4w66LY2ZrY2Lk6N9upHeASA/0d3hI5FiJfXS8+vZ1Tt14rRYoZw5Df1ZEcvTG9t/ICgO7AECYut4J7RwPnqDKmjbogXotrjVYWDrjc3YksUipnPffnRbGjN19oLIHTd1EukdEFoTjmve73DY1Tu+dq1IVr15M/pzIpanN7b/QFAc2ANE5vYDafNQNaxO7kW3xa0OA1tvbILjx091M0cQ25bGtOpjs6+kdzDo5ylbu3pHpkwUaZHYxAP7ORHL0xvbfyAoDuwBQuZM9OExRnzi9dvotrjVYWDrjU3Y+uXb+qOHo9vSmJHJ1caAfJH0DgiTR4/7lurKrt6h3kZi9FAC/TkRy9Mb238gKA4ZBggZa1G+cmBA0hPK5XQYMuiNqmvqBZ9sQGyWTAd7RGnE9q4mDia98Zl95N9BCzt6Z8MpEW/aszP6MyKWrze2/0BQHDIMEBBjx+Oy9h9Eb1QmM/efSp8ypJwOQwa9sRkeOcQ4CHIX3RaTVoqagb1J7wAxv+a51xVB7Oht1SqeXI3+jIjl643tPxAUhwwDBMTY8bispUvQG5VJa+tm7mx0W9zsMGTQG5tWbOeu3ei2mLRyxrn4eSO95aC1tX/Ona19N/SOb9wo4k3XrkV/PsTy9cb2HwiKQ4YBAmLsZIvLiq2Sv05xOR2GDHpjM3nkmHQVQWLLlhhOqXvpkEhvOWgd7tmw0dPr2NG7Id6UDoCoSnIACY4hwwDxSlyWJAdB3KzIIAvJIRC0EuD264lui0krDvbmPdI7YLTS+0yZ4Ol1StUb4ptDXdu5lnCciENyAAmOIcsAER411Ld8WcWYH7eTi2XR7XGzw5BFb3R9e3QUcVnhJL49qZeeHEwhveVgNmIcuOjekX/2vLpOqXpn7j2RvgY7sTS9sf0HguKQZYCw8mVJsOWafRIRHXa/Hui2uN1hyKI3NiHZMt8CO3UW3RYog+hFCATpLQ9htZlPOB6HPbtGqXrDYTs/axQTvdMb238gKA5ZBojU8VNim2T6VHxbTp4VtszAt8XtDkMWvbEZ37xFxGWtqUG3JbF9hzgEtXIF6R1QRmfPFJkOjp3w7Bql6g1Vl0TWhQPoz4XoTG9s/4GgOGQZICAZKV9169HJ022SUhhft044B5s2oT8XtzsMWfTGJsR28lW38aPRbYnOmuGJc0B6y8PEjp2eOPnl6A2prXi86b3H6M+F6ExvbP+BoDhkGiDMbZLMwxCqHdb2YMBOyJFD0EBI7g1JviHZdy7zKaotob7dxfbgkwjpHVCmr94UE46xIzy7Ril6w6EPsKO2azt+GAT7uRCd6Y3tPxAUh0wDBORA4yshBw+j2hHq3TWQJZLIIXiVdcMGolegydYlrYoMbq98k97ykGc6aPdBfW3Hjz2bcJSiN5QZpATQwSA5gATHkGmASOwxEkIvXohmQ5BLJJFD8CpjixeJg0fsc4dlAxxC4QPytMmkd8BZN3yQmHDcfuDJ+5eitxXe4nFOQqL3JAeQ4BgyDRCZOw9FeoIh/dFsSJ0+50vOLqwOQya9sQkrzfw05Lw5aDbE16wRA/LmzaR3wGlOOJJ793vy/qXobeU3vXAF/XkQneuN7T8QFIdMAwTEpNR2actjs7Dy70GQNl8V2roN/Xl40WHIpDc2Mw+eul5/1y7D1caAfNH9AZn0lovJA4c8Tb9STG/ev3ZuLfrX+DP050F0rje2/0BQHLINEJFJuCWKzLiw9I276M/Ciw5DNr0xKRJ+txfxnpG0/9fnA3IbzwZk0lsuZu4bCZgH9PLk/Yvpnblt7LAMHYD+LIju6I3tPxAUh2wDBGaR8iyckIOToV3aBvKEHDkErzMyeYKYcJzxf8KRufvI05AH0lsu8glHr85iwvE06rveVoz1ksXoz4Lojt7Y/gNBccg2QMBWGFZ+ttSJ0yL+b+ok9OfgVYchm97YhGB4PuFYt873ayd27jIOPS0ivTWhl5kOiultXfvQEfTnQHRHb2z/gaA4ZBsgeH62du8b6RLcq4taCmPLlor4v+070J+DVx2GbHpjM33+MtqEw8o3ySYepLcetOIAmTPmt96w9SxDnlWie3pj+w8ExSHjABEeMRglDg+24rDzwnndYcioNyb5hKP9h5zwvW/XZZMbK/4vmiG9NaFVZ7xXF1/zPmbDRr7J7h3RKy0R3dMb238gKA4ZB4jY8mViJW7nLt+uaeX/69Y+kPF/Zocho97YNE/i+nnwKH3FqAwxcijprRmtlbj7T3zTO3XspGf5Jok4JAeQ4BgyDhBQE5Vvk8yc5ts1rQ5y+hT0+/eyw5BRb2xCyh8ei8cmHn5dM75+vXHYaQ3prRkh0T2f4O7e45vekHpGJD3fh37/RPf0xvYfCIpDxgHCKo8F9Sp9qtMKJ+P8XnXE6DBk1BubUJmBn8Yd1Ne3a4bHjBBhDpeukd6a0ZzgRqZP9UXvV04fPw6j3z/RPb2x/QeC4pB1gLDiAK/c8OV6dYP6iG2Zu4/Q793LDkNWvTEJW/6hHp08S8/x2vXiuYaDTumXpLdmtMJNYILrYrhJIb0bJjh90O+d6B7JASQ4hqwDhLVFVlPj+bWyobgWAdLkEBSmlSJj/wHPr2WVG5xUTXprSkjGzCecN+95rndiyxYR4rBiOfp9E90jOYAEx5B1gEhfv+Nb1vrkkWMi5nDWdPT79rrDkFVvbCYPHfXtM2ClG9q2nfTWlF6UnCykd3jcKHHI6dwl9PsmukdyAAmOIesAwbflunf0ZVsuumiBESC9F/2+ve4wZNUbm6/EnXp8ChxiDfnqz+2HpLemTJ05L1aBJ473VG8RbvCBCDdIeRduQPSf5AASHEPmASI6b47Yltu739PrNKRleIp+z153GDLrjU2rDvT1O55dAyYz3NHs0dFzR5P0lpdQ+9lyzNLuJLxvSu/UyTPC0Zw8Af2eie6SHECCY8g8QFin5TwszZZ9XGckZu0c6Pg/s8OQWW9sxmtWi7jTDRs9uwaUAONbzXNmkt6aMzx6uJhwXL7umd6xRUbKmV270e+X6C7JASQ4hswDRC6W9fy0ZGLLVk/rscpEcgiap1WHeuwIz64RnTNLrGofOER6a06oP+1mHerGevP0L326Ufm3gJIcQIJjyD5AeB3AXDd8kJiFX7yKfq9+dBiy641JmGTAZAMmHRA75fr7w4DsY7oZ0ltupq/etPJPurH70FjvzL3H4v3790S/V6L7JAeQ4BiyDxDWCp0HVRpgVuxXPJYMJIegOCFWik84Tp5x/b3T1275mo+N9Jab/KBb3+7GgaAHrusNp8x537lsCfq9Et0nOYAEx5B9gIDEzHzQHNDL9feOb94sOsgli9Hv068OQ3a9sZnYsVPE6C2c7/p7m9Vm4hs2kN5ETivulH11W+/IBKPG9Znz6PdJdJ/kABIcQ/YB4pU4lgfuntK1Tn26FIQtO8khKE5+Srfte/W1XdrW55LPXXtfOOkZ6tZebP8+qiO9iZyQCojvQvTt7ngXIl9vfsq4/Yf1tR0+dPVzTJSH5AASHEOFAQIOaPCTbNt3uPae4Exap3812P41OwwV9MZmZMI4cVDj8FHX3jN18qw4YDLGuwMmpLd6hAlu3eC+RtnLm67pndy3X2RQmDLx/2/vzIPkqOo4XglltBBQi12jE0N2Z2dXyqMo/gArVaB4F39YSpQVgm4kwUCMUCJHBDnUABKBAIEEUzEcQhGCRDDhKE4VITEmAUISQrIhm509EyKHJSootX5/Pa+XzjCbnZme2d6e/nyqvun3ut/rfZ3Xx29+74r8GlF1hAEIoYnDB6LnydW5ZuALzq3YVC3ZO+90/WMWR359I/nCiEN9Ry1/ZZidc39WsXN2XD3PTTa+ivpG+yi7bFnuXbQ4XF+9YH3vvGiO68v6ZOTXh6ojDEAITRw+EMHO0taRvhLnfGnOj92v7g2RX99IvjDiUN9Ra3fPXq8J2JqC+7d1hD/frr5cc5xkYeobBTU4GM3WIu97NXR992/c8k7rRojzodEtDEAITVw+EP6AjV3XXxv6XH2btuVekGednpjmX/+FEZf6jlqdNy2s2IANW8nGa467ah71jQpq58U/cdNdrQ5d3zbq17t3b7st8utC1RMGIIQmLh+I/p3dA+3Tp3pelP6OnlDnyt5xR67J5TdLIr+ukX5hxKW+o1bv+udyPxLOnh36R4JNLF2tqWWo79rQ4OjzBdeFqu+333zTW896JAcboWiEAQihidMHwpbP8vpR3f27ss/hdbo+z3W6/ltlmpPjIgyC4rXPfbJmXdnnGVxqcNb0iq35Sn3Xnvp3ZHOjz2dO87oglFvfrz/l1v69rHL9V9HoFAYghCZOHwjrrxfWK+Mvjm6z4yep+dd/YcSpvqOW/dAI65WxdYWjmmuS+o6XbNCRN/r8kcfLru+uyy/NnePR8s6B4iMMQAhNnD4QnlfGDd7oefLp0vPL4PPzdz/0cOTXE8ULI071HbU8r4y/FnV2T8n5vfvtnDMj8zZT3/GSTTvk/Tg9/0dlDd7o3+L6Nv9gRtXWTkejRxiAEJq4fSC67luZa+KYd0XJef3pPby1NxPm/fNfGHGr76jVceVlZU/fYl6YSq71Sn3Xtvb5gbrqgZLzZ29emhv8oW3U14KqLwxACE3cPhDeDPcz20qeosN+UfvemJ7H/hj5dUT1wohbfUct8zTnRoyfUVLfLO9j7voQltukR30nT/6cp94ULiWs4LG7s39gx6wZucEfW7ZFfh2o+sIAhNDE8QPhr6nauWhh0Xm6738w54258LxEev/8F0Yc6ztKmedu588vLnnw0aC3+fyzI7vfqO/4ye43fw3fUqYg6nTev57586jvhAgDEEITxw+Eef6sX5Z5AYuZGNr6w/jrCSd5YXQMgvJk95jnlTnjVM/TMlx689zYIKOovc3UdzzV9+zm3Ijg77cN9O/oGj69TSRtU2SdOnXgzd4e6jshwgCE0MT1A9G1/O53locbpsN0171/yC3tdcmFkfTFGi3CIChfHVddmRsRfN38Ye8h30Pt3W8Repup7/jKRp57rRw37b+Vw/MYun6q2aVLqO8ECQMwIbS0tMxMp9PHDJcuk8nMaW5uniLNVfhjxZw7ri+M3X2vDC6i3rl06E7Pfc+9kFvWy0Zirl4bebmjfmHEtb6jlnmdbS6/XAf9+4dM5/cZNO+NeWaob1SO+rfvGmifcYo3Cr13/cYh01kzseednn3awO7OPuo7QcIArH3GyZCbLQNwnYy6z+4vodJNVrolFtZ2gtKvKOYPxPmF0bthY64p2PpnLb/7Xce9j/aZp5fcX7BWhUEQTtZ9wDPu9GEu1JWg9+m13kS+wxmJ1DcqRtnbbx/setD3zKZ3HfenjbHm3961z1DfCRMGYEKQMXfLcAagjL4LZQSeFsjTVcy54/7C8Dwup07NNc/Nv8rz+JnhZ82+vsfGpoxhUXQMgkrI/yh7PypuuXmg7/mt3mof2WXLcv2w3KTPo6GrAfUdb1n3gV03LsjdbzICu5YvH+hv7xzo2/TiO/vtx8YDD1HfCRQGYEIoxgDU8QXSyYF4tr6+/qDhzm0vjL17czdTXNXz2BODzbz52nXNrwb29LwceRlHg6yea6G+o9SePa8PdK9c5a1JXeh+67prmZcm6nJS37WhPbtfG+hcdGPBe828zd0PPEh9J1RWz5WwL2CUU6QHcGEmk2kNxHtTqdSB1S/d6GBr2wmHtk9rvXr7tG9v3T6tdUt7W+vjL7a1fj7qckFt0t72zSN1jy2RNm1va+3Wfbd4W9uJw/bTBSiHrW0nTtZ77R4Zflm959brfrul/ZQpRfXzBoBRigy1Y2XcrZFWB7Qm2IevhCbg6YF4TzXLDQAAAABVpJABKGOvKRiXwXe0eQEtnE6nlbx55UiWEQAAAAAqhAy9WTLmNku3Knyc2z1G8R2KH5KX9goZgSdJVzY1NWVGvrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUCItLS0z0+n0PisYZDKZOc3NzVOkuQoz23wNono/QpsDbLlApgyqPXiGkwXPc3LI/2bzrEM5jNPNMls307rgJNPaN1n7llhY2wnBFUmgdlC9Pqv63Svdm0ql6qIuD1QOnuHkwfOcCN71zeZZh1DkrzLilpQ7LXC8K5qSQTVRPbdFXQaoDjzDyYPnOTkEv9k86xCKfANQ4QXSyYF41poVoikdVAu3Wszx2l7Q0NBweNTlgcrBM5w8eJ6TQ/CbzbMOoSjgAVyoXxStgXhvKpU6MJrSQRUZY//U1dUdrPpfE3VhoHLwDCcSnueEkOcB5FmHwuhmONZeBtLqgNYE+wkM0QQ8PRDvGelyQ3iGqHvTiqampm/o+HyXdKz2vRFpYaGi8AwnC/c8X+OiPM81ToEmYJ51KI8CBuDR9qvCwul0WoeaV0ZXOqgG+mB8QXV7lIUbGxs/rjp+JOoyQeXgGU4WPM/JIs8A5FmH8tAvh1m6YTZLtyp8XGD/FbqpTnL9SphSoAaxjsP2y1F1/wtGDdYePMPJguc5GRT6ZvOsAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMSTlpaWacUuIZbJZC5V2mXl/B3l/Zz+Vl85eQEAAACggjgDcHUxaZ0BeGc5f8cZgL3l5AUAAACACoIBCAAAAFAiMojOlbIybv6h7Q4ZOq2BY+dLL+nYy9r+ftKkSR/1j2lfh8u7QeF/antPQ0PDB5X/NoVf176NCn/CT9/Y2Dhe++7SsX6p04yxocqkdPcpzeJAOa6VHh4i7T4GoOLX2PnteqT1wfXCnQG4Qvtvd9e7KXi8rq7uYMV/LXWZsaf0N2j3OJcXAxAAAADiTzqdbpGx84a/DqcZaTLiDrew9n9PBs9OW6hdxs97FV+k+F/8vGYASuuU/iOHHXbYhxTeJr2odF/W4THaXh8w2iy+1tZ7Vfg9lscMR513RqFyTZgw4VAd79bxr+ucXzKj0cpWKG2+AajwyVYeBccqfJa0W3/vfXbMDEClf0v7ptpxhdsUflXX+AGXd4W0dPz48e9X2kN0/CHF57q8GIAAAAAQf2TQpM0A1PYE30jy0f5HpTP9eH19/UFmPE2aNKnR5TUDsC2Q/nrFH/TjMpgma98el/ZoqSd4fh3/jvY9PlTZzJC0/OaNU9qv7eca9tsErOOvKP+R7m+aAbgu7+88YwahjtXb9ZnxF8h7rHlAXV4MQAAAAKgNZNh8S0bOn6zZVlplXkHbr/AL+YaXjYLV8WNcuEPHvxI49kvluTkQP0Lxf7m/caLi/zVjzGReN+k1hZ/fT9HGOq/i1v2Vv0AT8DlWdvc3TP9zXsnBJuC8/Pdq33m6rqO0fdsvoyvna/b/4vJiAAIAAEBtYR5A12z7Z4sP5QFUugaLl2IAavsZa04upTw69yU2vYt56BQ+e6h0QQPQPHbSXqX/ZOD4K345h/AAbjAPoDUxa/sf7TpgiPJgAAIAAED8MW+f9EXr46foAdpeLiPnCTtmfQCt+dP6AJpxqP0Lpaf8vEUagP920bGuD+BFqVTqQMXHWL/D4ACMIM5g/Ls1N9tAEvPkKf2nCqUNGoBKc7x5Kd1glXHa/1PzPOYZgG9JJ7nr/a6d2wavuL9rfQAX+XGdb6LSfNXlxQAEAACA+CPj7tMyeP7qRu1as+djfhOwGCOjZ4557syrZiNzJ06cmPLz2v5iPYCGjKkP2whh6wvommY3BEcc+1gfPB1rN8PO32eeSNdcPC4/fV4TsDUbL3HXY3/n3GA5XRPwPdr3WzcKeLMZdv65zMvp+jLucs2/mxX+ocuLAQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwmvk/2k5ULfcPTpwAAAAASUVORK5CYII=\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# We can also pass these options directly to the constructor\n",
|
|
"# Here, we force the legend to be at the best location\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\") as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# But we could also not constraint it (best location will be choosen)\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\") as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or just say we want a legend (same as not constraining it)\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=True) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
"\n",
|
|
"# Or force it to be in the lower right corner\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"lower right\") as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or explicitly disable the legend, even if labels are found\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=False) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nO29B5Rc13WmK5IW7VGwrBnAsCERobu6xiNLz+O3nuzn9STZM/Nkj2Y9r3GUGSRGECQIEsxgzmDOAWAESTBTDGAGcyYYQDCCEZ1zg2C0FSyKrHf2vbcKhUaHCvvU2af6+9f6UaEr3Prq7ls/zrnnnC98ASGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghZeXz+X9ta2v7wSSP6crlcrvX8z7uPc51HnGv9Yl7rT+u57Umk3v9v3Tv9bm7urXm67rX/KHb/rfd5cfu8lR3uaO7fEvzPRBCCCGEJpQLILtJ0HGB55TJHuuCyi7usX0TPWa84FRvAHTP/b/d6/5qzpw5f1Dra4wn97pXue27ZtT7yef47AvKAVDCn3vtgzRfEyGEEEKoKrlA8oILOhuch93NL070WPeYXZ17J3qMCzd/lQWnbUa9T70B8CeTvXcFGvPzNTgAftra2vrfNV+zAk34vSKEEEJoCqmlpeX/kpDjws5fS+uadEdO8Njvub//0vk30uUr3bDu+g7yN2nxk1DjvJ27/gt5zeJj3GsfLo8ZHQDnzJnzR+5xd0vwlFZF9/elM2fO/NJY7+3+dnz5e7vL17Nt+pp7zcvk+VmIvdfdly8+z/3tOPf4p9z9J7rLAXe5bozXPsL5187/XrbN3ywGQOd/dPe9I122zg/Onj37D8te/7el5dTd3+4e8767fNz5v47Dry3bdnnNX8j7OF7/z+hW1enTp3/F3b7a3b9RAq/zoozPztl7btHCOvo1skB7s7tcVuQi92+33XYz3fXrnfsz7tc75tPG+84RQggh1ISSoOC8Nrt+owsNT0/0+CxobNEKVwyAcr2s5WyrUc8tBcBvfOMb/ykLJovczd/65je/+R8lXDlfWs17S4B09z/iXne6C5S/k50j2FsMklkA/LW77yh3c1t5zHgcxmkB/Nzdf62EsmnTpn1V+Mhjy553dVko3No9Zx85R1GC6XifI2P138b7XO76lc7PzZ07d4Zsr/v75Vk4LQ+Am7VMjvEaV2XP2cXd3Cb73NvKuYbub6fLbWHkXmuFbP9424oQQgihJpMLAb/nfvx/7kLBfLktoUSChQsv3xnvOVUGwHHPAXSXB44Om9IaJq2QXxgVHMd7bzkXMHvfb5c97Lfc495zr//j7H2Om+ycxWz7x+0Cdvd/o+w+CXhvyPUsxMr750a91rsTtaSWsxrjc20lDNz7/E3x7xI8s5bPagPgM+Xv627//WgW8tlke6RlcCI+CCGEEGoSyUAE6ZKU1q3srq2y8HLxeM/RCoDSNZm1UH1QtLvvIwmk5V2sE723C6rflfcZ3W3sHveiu/+QbFuOm6xVM9ueis4BLN8Gd/3PshbC8s/wobv8N3e5eIL3GjcAuvt/X/7u/F9Gfab3qg2AzteNet/Fcv7h6O0V5jLAZjJGCCGEEGoCyXltWQgbdB4SZy2Cn5SFws3kgsJPJwuA7vnfr6AF8Fh3++Eqt3esFsDRLZbbSNeye/1/zt5HWgCfnOy13WOWVxsA3fvOakvPn/xmNZ+jkhZA9/f/WbYdvzuqBfD/lPeVlsGy1zhyjBbAzT6PPN/dv76abUUIIYRQEykb9CGDEX4grU5lzkmroPv7wrGe5x7/QxnAIOfsjbq/FGpksEMWjL5V/pjyACiDRWTQhHSputf6D8X73O3/Pd42j3cOoJzDJtsur+Mec7Z0c86YMePL2eesKAC6x52cdZluXXZfJS1ttznfKWFQbksok/Am5++N916TBMDiOYCrJeBK66a7fkn5OYDZIJGPslZOCYz/VdhOFgDlee6+bve3EyVUyn3CrdhdjhBCCKEmlwsBtzvfP87fZCDFFqNlM0kLmwwW2Zh1I26fPeez8lDTtmnC5g+K3aHuemf5KGAZrSvbIS2QWVfkumywxpgaKwDKeYzZKOD+rJv0Phe+/nPx75UGQPec2RIAi12j5aOAvzBBAMxGAR9bNkpYRtfeOtFchaNZjX7NslHAMqpYRjfv5zxcHtQkKEtrXjYS+14ZaT1ZABRJ93pbOnClJwuR77rnXjgZH4QQQggh1EBlg3WktfbPQ28LQgghhBDyoGwuRVlWb+tspLG0uMpScaoTUiOE0JRRLpfbyR1M/9H5fHdA/V+htwchhEbLHada3fHp1bZ0rWCZDFomt24LvV0IIRSlZs+ePVcOqnJdTtJ219eE3iaEEEIIIeRZs2bN+rpcyonmcuJ26O1BCCGEEEL+9cXW1tZ/kTm/3PVtQ28MQgghhBBqkGTqCuc7Knns559/XkAIIYRQXPKdJVCEyiaq/XzmzJnTJnus7EQbN35SeO89XI+FISzhaMmwhKU1w1GXZSPyBIpA+Xx+Txf6bpHrMsWCTNj6hQqmVZBilJ1pwwZcj4UhLOFoybCEpTXDUZel92CB4pAszeRC365Z9+/lo9YPHVcUo14xwhKOlgxLWFozHHVZ+s4VqMlFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbOD8iQcrncAud5bW1t18+dO3d2Jc+hGPWKEZZwtGRYwtKa4ajL0nemQJGotbX1R87fzq7/nQuBd1fyPIpRrxhhCUdLhiUsrRmOuiz9pgoUjVzgW5TL5S6U6+7yW+72K5U8j2LUK0ZYwtGSYQlLa4ajLku/qQLFpG1aWlq+JleybuAzKnmSFOPGjenOhGu3MIQlHC0ZlrC0ZjjqsvQbKVB0mjZt2ldd+Lt9xowZX67k8QWEEEIIRSffeQLFpa1c+Fsya9asr1f6BNmJ+N+Yzv/GYAlHS4YlLK0ZjrosfYYJFJny+fyec+fOnSHXXRD8h0qeI8UoO1Po8xlitzCEJRwtGZawtGY46rL0myhQNJKRvy4AfuKC34bMV1XyPIpRrxhhCUdLhiUsrRmOuix95wrU5KIY9YoRlnC0ZFjC0prhqMsydH5AkYti1CtGWMLRkmEJS2uGoy7L0PkBRS6KUa8YYQlHS4YlLK0ZjrosQ+cHFLkoRr1ihCUcLRmWsLRmOOqyDJ0fUOSiGPWKEZZwtGRYwtKa4ajLMnR+QJGLYtQrRljC0ZJhCUtrhqMuy9D5AUUuilGvGGEJR0uGJSytGY66LEPnBxS5KEa9YoQlHC0ZlrC0ZjjqsgydH1Dkohj1ihGWcLRkWMLSmuGoyzJ0fkCRi2LUK0ZYwtGSYQlLa4ajLsvQ+QFFLopRrxhhCUdLhiUsrRmOuixD5wcUuShGvWKEJRwtGZawtGY46rIMnR9Q5KIY9YoRlnC0ZFjC0prhqMsydH5AkYti1CtGWMLRkmEJS2uGoy7L0PkBRS6KUa8YYQlHS4YlLK0ZjrosQ+cHFLkoRr1ihCUcLRmWsLRmOOqyDJ0fUOSiGPWKEZZwtGRYwtKa4ajLMnR+QJGLYtQrRljC0ZJhCUtrhqMuy9D5AUUuilGvGGEJR0uGJSytGY66LEPnBxS5KEa9YoQlHC0ZlrC0ZjjqsgydH1Dkohj1ihGWcLRkWMLSmuGoyzJ0fkCRi2LUK0ZYwtGSYQlLa4ajLsvQ+QFFLopRrxhhCUdLhiUsrRmOuixD5wcUuShGvWKEJRwtGZawtGY46rIMnR9Q5KIY9YoRlnC0ZFjC0prhqMsydH5AkYti1CtGWMLRkmEJS2uGoy7L0PkBRS6KUa8YYQlHS4YlLK0ZjrosQ+cHFLkoRr1ihCUcLRmWsLRmOOqyDJ0fUOSiGPWKEZZwtGRYwtKa4ajLMnR+QJGLYtQrRljC0ZJhCUtrhqMuy9D5AUUuilGvGGEJR0uGJSytGY66LEPnBxS5KEa9YoQlHC0ZlrC0ZjjqsgydH1Dkohj1ihGWcLRkWMLSmuGoyzJ0fkCRi2LUK0ZYwtGSYQlLa4ajLsvQ+QFFLopRrxhhCUdLhiUsrRmOuixD5wcUuShGvWKEJRwtGZawtGY46rIMnR9Q5KIY9YoRlnC0ZFjC0prhqMsydH5AkYti1CtGWMLRkmEJS2uGoy7L0PkBRS6KUa8YYQlHS4YlLK0ZjrosQ+cHFLkoRr1ihCUcLRmWsLRmOOqyDJ0fUOSiGPWKEZZwtGRYwtKa4ajLMnR+QJGLYtQrRljC0ZJhCUtrhqMuy9D5AUUuilGvGGEJR0uGJSytGY66LEPnBxS5KEa9YoQlHC0ZlrC0ZjjqsgydH1Dkohj1ihGWcLRkWMLSmuGoyzJ0fkCRi2LUK0ZYwtGSYQlLa4ajLsvQ+QFFLopRrxhhCUdLhiUsrRmOuixD5wcUuShGvWKEJRwtGZawtGY46rIMnR9Q5KIY9YoRlnC0ZFjC0prhqMsydH5AkYti1CtGWMLRkmEJS2uGoy7L0PkBGVQ+n5/f0tLyvUoeSzHqFSMs4WjJsISlNcNRl6XvLIHi0ra5XG6hC4Br2traflDJEyhGvWKEJRwtGZawtGY46rL0HShQhHLh7yoCYOOLEZZwtGRYwtKa4ajL0neWQBGq2gC4cWO6M+HaLQxhCUdLLmc5/MY7hb6bbir0XLy00HPFZYWBhx4pbBh8P/g2xmLf++XQy68X+m68odCz9IJC71VXFgafeLqwYfjD4J87No4+vGHDx4Wh59YUeq9ZkdRP74qrC4Orny9sGPkoOEvfWQJFqGoDIEKoOfXphx8Whi4+v7B+l3/Zwp0HLCj86wvPhd7EKa1fv7eh0H/GkjG/n65D9iv8/I3XQm/ilNavursKvScePeb303vcEYVfdqwPun2+swSKULQAhvnfGCzhaMkjr79Z6DpwQfqDtdeuacvf/Q8W+leuLHQev+lHrf/224Nvq3X72C8Hn12TfC/yHbTvu2fSsjTwwEOFvltuKXQeeWjp+5HboT+/ZY6+PPTC2sL6+bsk30HHgQsLfddfn34/N95Y6Dh4v/T72X0nV1MPBGPpO0ugCMU5gGHOx4AlHK14+O3OQvuCPdKWpFNOKgx39G/295GRjwv999xbWL/r9mlrhgsfcl/o7bZq7f0yCX/zfpqw777gvMJI34bNv5/hjwp9K+8orN9txzQE3nxzcAYWOfry4DPPl76fnouXFUYG39/8+xn6oNB77bVpCHQ1NCBd9gFY+s4SKDLlcrkFLvytc77aXf+ryR4fQzHG4FgObNYNx/o9MrCx0JG1IA0tPTc5l2y8xw489mRh/R4/SUOGCxyht92qNfdLCePtC+el4eLKKycM3hIskhDoQkZy3pkBFlY4+vLg2ldLNdGz/IoJv58kpEsInL9LYej1txvOsgGRAjWzrBdjLI7hwBaD4Vif5ceq+/xz026rIw4ufParX03KcuCp1emPmPvRG3r9neCfwaK19ktp2es6+cS0ZfbM0ypqde279ba0m3jhnoXh9t7gLCxw9OWRgfcLHYcekIXz5ZN+P/J3GRiS1NtB+xaGuwYbyjJ0fkCRy3IxxmTrB7ZYDMf6nHTrSpjbe7fC8NsdFbPsueLy9EfsyEMLI4MfBP8c1qy1X/bdcmsa5hbtXRjuHqroORIyus44NR24c8IxSYgMzSM0R1+WFtmE81GLCyND47ecb/b9DH2QfC9Jd/55ZzeUZej8gCKX5WKMydYPbLEYjrV7pGe40L5Pet7fwONPVcUyaflYfGB6PuA1K4J/FmvW2C+ldXX97ll37nMvVv/dHrgwHbRz973BeYTk6MuDL7yUnhO7+05Vd+dKt35xQM/g8y81jGXo/IAil9VijM2WD2wxGY61W7qskq7F00+pieXQK2+kAcVZBpGE/jyWrLFfFlvxpJWplucPPJl21bfvN78w0v9ecCahOPqwtPYVu377bv5ZTa9R7KpPWtEb0EpLAER1y2IxxmirB7bYDMfaPPRme9JyIQMGhta9WzPLnksvSbuyLrog+Gey5Hr3y6R1ScLb3rslrXm1vEbSFbzk+LSV9vobgjMJwdGX+1c9kIa3ww+uObxJV3DHoftnrbT3NIRl6PyAIpfFYozRVg9ssRmOtbnrrNPT1qXLL6uLpQwySKa/2HX7UpDE9e2XEtyK8y72/eyWurZj6OV1aTfl/J23mNonBlus76T176B901MnHn2irtcaeOrZNOjvs0dhpHfEO8vQ+QFFLmvFGKstHthiNByr99BLr5dal8oHFtTKsueq9ET47nPODP7ZrLie/TKZyiUb+CHnWta7LTJvYBL2L7k4OJdGcvTl/ntXbeq6VZgLs+vUJdkE3rd6Zxk6P6DIZa0YY7XFA1uMhmP17j737DG7BWtlKVNZFE9olxan0J/PgmtlKYGiOCdj/z33qWzL8Dtd6bmae+xUGO6MqxXQWn1Lt237AfuUBk5pvObg82s3Bf4hfyPqCYCoblkqxpht7cAWq+FYnZMwsNsOSbftcNeAGsve667LprU4J/hntOBaWcpo3yQMuJBR6bQilbg416N8T6HZNIKjLxdb/zqPPkxtJZyky//YI9PQv+oBryxD5wcUuSwVY8y2dmCL1XCszj3Ll5eWq9JkKWFSWpiSEcHtfcE/Z2jXyrJ4bma95/6Ndqnbf+G8LZYps2xr9d15zOEq5/6N9sAjj6fdyocd5G2JRQIgqluWijFmWzuwxWo4Vm45yTzpqpUBG29sOWCjXpbdF56fdS1fH/yzhnZNA2qkdVYGbMz7aWGkwkmfq3Fx8mFpxQrNxydHXx567a3SCivaXbUykrjjkEVpuHxytTeWofMDilxWijF2WzqwxWw4Vu7iqhIyv5wPlqVWJpl3zuO5TDG4pil1ssE0vgZrSKtVaeoST61MFjj6cnH1G/mefLx+/133pPV58gneWIbODyhyWSnG2G3pwBaz4ViZk8EFB++XrjwwzqoSGixL5zI9+EjwzxzS1bKUiZplVHYykMbT+spJK9OB6fQlg6tfCM7IB0dfluUOi6vm+JruaGRgY6mFXlqDfbAMnR9Q5LJQjM1gKwe22A3HylwcXNBxyP7jtv5osOx/4KH0JPnjjgr+mUO6WpYy4tdn60/RxdUnZFBIaEY+OPrywMOPpfv18X73a2n99TVYhwCI6paFYmwGWzmwxW44Vubi+Xl9N9/slWXSUrJwT68tWTG4WpbFiZ9lMIDP7ZJpYGT1l+Q8wxpXGLHM0Ze7Tj2pIedPlk6j2H+B+vJwBEBUtywUYzPYyoEtdsNxco/0bSis33PnZPoXWbnDN8viSOPeFVcH/+yhXA3L4bc60h/9Bbs3ZIRucY3h/rvvDc5Jk6MvD7/bXVpNxfeaysmpGocfnP5n4Kln1VmGzg8ocoUuxmaxhQNbMxiOk7s4d1nXaUsawnLolTe8tWLE4mpYFudQlHWVG7FtxcEgMXTTW6jv3htuSLvNl17UkPfru32ll5V1CICoboUuxmaxhQNbMxiOk1vOW0paFB5+rGEsi60YsQw20HalLJMWn+LAjLWvNmTbNhvQ8Mb64Kw0OHpj5f4D037gwvT7WfNyQ95TlmdM59TcKVllR5Nl6PyAxlE+nx9yHpzMobeTH1u9YoQlHH1bfuBLi80PTjw1iyZLmcg4acW46ILgDEK4UpbFZcA6Dj2goVOz9Fx+WdpNf82K4Kw0OPry4Orn0+9ncWO/n+5zzkrP2b3zLlWWofMDGke5XO4vK3Ho7eTHVq8YYQlH3+698ca0e/GySxvKcnh9b3be1C7ez5uy6EpZSrdiEsRuGn9wjg/Lms0xdNOHrm9Z2jAJYrfc2tD3La4M0rXkeFWWofMDilz82OoVIyzh6NsdRx464dx/PlnKlCbJYIMHHgrOodGuhKUM+CjN+/Zud+P3jcUHpvvGi68E51UPR1+WUdLr9/hJurxh50Bj39v9p0lGaicDt5S6gQmA8Wjbtra2k5w7nD+WO3K53N/k8/l9Q28YP7Y6JrjA0bdLo0tl/dcKWnm0WfavejBtxTj9lOAsGu1KWA48+Uw6GOOEY4JsY++113pd2aJRHH2574470/33rNODfPbus89I/wN1z31qLEPnB1SBXNi70IW9Vc7fdwHwI7mvtbV1O3d9Xeht48dWxwQXHQ88+nih98SjCyMTTG8yVV1c+q1n2dKKHq+9TyYtKLvvmLSiTLVu4EpYdi9Lu3/7brs9yDYWu4FlhRirS8OFPE6W5mZ84ukgn11W00kC6KkTj96vhmXo/IAqkAz2cCHwd7PrHxTvL4bBkCK06JgAqOPebP3UiSY4nqouLstW6XxiPvbJrlNOqmgEcrN5MpbJ6NKF8xI2w293BtlGCX3FEa5Dr70VnFktHH05mTBbzmHda9dJB095+356N5S6oDUm7SYARiIX9PpmzJjxZbleDIBz5sz5PXe9O+iGfYEAqGUCoI6Lo/RimNOskR5e35NwWb/3boWRocp+wHzsk3133h3V0mNanoxlafTvkYcG3c7SpN3XXx+cWS0cfbm4NF/3uWcF/fylSbtXPajCMnR+QBXIBcBLnJdLCMwC4Dbu9jLn80NvG6FFxwRAJbtw0148kb6rsSdqW3bfyvT8pe4Lzqv4OT72yeH2vrQlpYog2gyejGXP8iuy4HVD0O0cfOGlNIgefnBwZrVw9GU5bzUJXg8+EvTz9696IO0GdkFQg2Xo/IAq0LRp077qwt5tLvz92l1+5vwruT19+vSvhN42QouOCYB6HAcvPEftf8nN4s4Tj027Xh97siqWPvbJYlf04NPPBefSKE/EMul6PWAfE12vSVf0vvPTbXmzPTi3ajh6YyJLJyYTMe9YGOkdCfv9lJ9H67arXpah8wOqQrlcbnpLS8t3586dOyP0thRFaNExAVCP48dPPZ4tnRS2u8aKpSU0aXXbc+fCyEDla8v62ieLk0L3XHJxcDaN8kQsrQ2+6Ll4WXoerfueQm9LNRx9uTQH38knBv/84q5T0/No+x+qrzWSABiRXPD7Wltb247Oh8qlnAMYeptEhBYdEwD1OH768UebTtieQt2M47n/nntrWkvU1z5ZWo1k0V6mJx3W9EQsS9OvXGlj+pWBp59Lz6M99sjg21INR1+W81W1V+Gox6V6PvuMulmGzg+oArnA9wPnD51fyufzK93lWrnNSiDNYwKgLsfOY49IuxmfXRN8m0K71hYDn/vkpkmHG7PebWhPxLLjsIMaurbsZJb/NMk5msmI5PW2plNq9HFSWLQbY5G06O+2Q9aiv7EulqHzA6pALuy97oLfzuX3ufD3U+YBbB4TAHU59hWXPFu+PPg2hfSmc4Z2qvqcIZ/7pKw5mwx6uPrq4Iwa4fFYynl2SWvofvNNtYbKYKGk1euOO4NvSyUcfbk0q8Axhwf/7OXuPOn49JzeR5+oi2Xo/IAqkAt/n7iLrUfdvU12f1ARWnRMANTlOPzqG+l5VYfsH3ybQrr//tpX3/C5Tw699Hr6/Rw6Nb6f8VhaPbpx63IAACAASURBVB9y4NEn0+Bzkt7asz45+nLP5ZcFWZt5Mkt3dNINfN45dbEMnR9QBXJB71o572/Ufds7XxNqm4oitOiYAKjLccOGjwvti/ZORzO+sT74doVy15mnpd2/991fM0sf+2Qy8nX/Ben3s+6d4Jx8ezyWpcm5jY2Ilq5F7bVnfXL0wsDwPlqaTimZmLrygV2jWYbOD2gcucB3o/MNmZMpYJzXZNfXZFPC3Bp6OwktOiYA6nMsjWYMtLRWaG9aQH7Hwkj3UF0sfWxfz2WXmmxd8eGxWA6391Y9OXcj3VVce/beVcG3ZSKOvlwanW20F6HepekIgIaVy+WOq8Sht5PQomMCoD7HgcefMtmN1SjLcmvp9BUn1M3Sx/YNrn4h/X6OtnV+lQ+PxbLvjrtMr4rS/8BDNZ8+0EiOvlwcnd179VXBP/dYlv/YJqcPXFzZ2t5jsQydH1DkIrTomACozzFpAZO1M3cLP4FrCJdO5K9x+grf++TI0IeF9gW7ZyMse4Lz8umxWHYtOSFtwXnk8eDbN+b3U8cAokZy9GVZDSUZnf2CjdHZo10aQLT/gprmjyQARqQ5c+b8Ti6X+9O2trYfusu/Ljr0dhFadEwA9MOx67Ql6Y/sw48F37ZGOlnRYeGeabh6p0uFpQ9bHW2q7dEsk3Dl/mMiXfTyH5XQ2zeeZfLjdLRp5SvINJKjLw+/1ZGGK1dDlkZnj7ZMHl7rCjIEwEiUzQM4IusAu8vfyKXzp86dobeN0KJjAqAfjqXRcheeH3zbGunSKNvDDlJj6cMyjUXSzbikubvpR7OUORmtda+O5b7bV6bdjMtq62b0zdHb5771NlOfezwXRyn33fyzmliGzg+oArmg96ILfovkukwAnV0e5XxI2C0jAGqZAOiH4/C73en/5PeZZ/p/8truvf6G9AfsqtpXl2jEPpl208s6q3a6GX14NEv5D4ml1SXGc73djL45+nLnCcekLZ9PPhP8M0/kgaeeTc+jddtbC8vQ+QFVoPJ5AIsB0Glbd/9AuK1KRWjRMQHQH8fSuTwvvhJ8+xrlzmPqXwmlUfukDFJJfmwfs9HN6MObnZsq3fP7zq+re76Rrqeb0SdHX++Rds/vkHbPV7F2dgjL9hWn65HtrpZl6PyAKpALfT2zZs36enb9zVwu98ezZ8/+Q3f949DbRmjRMQHQH8fSqhPXXBN8+xrhZKkomSNs/i51TS/SsO620mjGZcHZ+XI5y1L3/OIDgm9XJa6nm9EnR1/vURo9f9rJwT9vJZbTCGo5z5kAGIny+fzZLuztkF0/2Hmj85Dz5aG3jdCiYwKgP46yxmryg3vEIcG3rxEuTd9x1unqLH146I13027GA/Yx0c3ow+UseyNbpnDgydVpN+OJxwbfloYMTFp6YVQDk0rnOV90QdUsQ+cHVINc8Pt+a2vrj76w5fJwDRehRccEQH8cky63fealXW7vdgffRt+W5aGSCXzvuVedpQ9L6Os4cN+0m/F1WysuaLmcZXH1D1lnNvR2VfT9lFYFCT+dkvepiWT1j0V7pceKtzuCs6/EchpB8h+ofatbT5oAiOoWoUXHBEC/HDfNiXd38G306STsLtgjm1uv1wtLH+659JL0+7nl1uAMfbjIcqRnKOue37kwMmhv9Y/x3HXqEhNzFvreJ4deedP06h/juWPxgel/oF56vSqWofMDGkdtbW3POq+ezKG3k9CiYwKgX46xnddTq2Wgi1Z3dyP3SVnOqpmngymyHChO/3LGqcG3qRr3rbwz7WZceqEJjr72yb6bb06756+4PDjzatxz5ZXpec7X31AVy9D5AY2jfD6/SyUOvZ2EFh0TAP1ylK6rZOLdPX5ieuLdel1avmrFCm8sfbjZp4Mpsiy2RPffdU/wbarGpYmR99sr6HmavvfJ0vQvTz0bnHk1ltH+yXmaxxxRFcvQ+QFFLkKLjgmA/jnKmsD1LJ4egzuPWpyeX/b8Wq8sfbiZp4MRhp9/9lmhfWG856JKt2jSzfjKG0E5+tonS/9JjGD6ly22feiDZNS/nF4gswBUyjJ0fkCRi9CiYwKgf47NPt3IcEd/8vnW771bss6uT5Y+3MzfjzD8ZVdHNv3LgcG3pxZLt2jSunzTzUE5+ton5fzG9DSRJcFZ12IZ9Z+0Lt//YMUsQ+cHFLkILTomAPrnWFrVYNHeTTndSP9996fnaZ1zlneWPtzM08EIw/fvuDUNuFfWvjpLSA88/VzazXj80UE5+tonu5delA5EWhnH9C+j3X/PfWn9n3d2xSxD5wcUuQgtOiYANoZjxyGLgndj+bIEv6QFwAXBRrDUdjNPByMM+046Opv+5YXg21PT9zNY+6oTmhx97JObTf/yVhzTv4y2jPpP/gO1YPeKpoMhAEaiXC43PfQ2jCdCi44JgI3h2LP8irQb68Ybg2+rpqXLV7p+kx+wjv6GsPThZp0OZqR7MMrpX0a7tOrEQ48GeX9f++TQq8XpXxYFZ1yPO448NP1PxgsvV8QydH5AFaitre1Xznc5/6O7+UVf7+OC5mHuPf7B+SR3/ZuVPIfQomMCYGM4SutLtaPlYrAM+kg+11GLG8bSh5t1OpiBB9PVWbrPPC34ttTj0qoTF54f5P197ZOyzF3SPX/5ZcEZ1+NNy15OPgsAATASzZkz5w9cKDskn8+/mi0Dt7SlpeW7mu/hAt9fFJeWc5ffcO93WyXPI7TomADYGI7JaLm9dk1Hy3XqtJRZcO+Kq9MD/7XXNoylDzfrdDDdF5ybds/fHdf0L6Nd66oTWva1T8oyd+n0L6uDM67Hgy+8lLZkHnloRSw1MwRqgFxQ+1MX0M5xHnQh7U1ptdPoInavd6R7nXnF2+61+yp5HqFFxwTAxnHsPudM1XPlLFgmfk66ftZM3vWjydKHm206mPKlCEfWxzf9y2h3LD6g6lUntOxjn4x5+pctPstmKwH1TMqy3tyAGqy5c+f+Hy6sne085PyitNQ5f+zC2z71vK57jQucdyi73Tt9+vSvTPY8KcaNG9OdCdduYQjLxnAcuP+BtBvr7DOCb6+GRzqKJ3/vUdgw8lFDWfpw/+3ZdDCXLAvOVsNDa19NP89RhzZFffdeuTw9T/PGGxv+3j72yYFHs+lfTl0SnK2Gy1ubJ2NZT2ZADZILfTNcwDtIuoBdMBuWANjS0vKd4t/dff/F+aN63kO6ld17/Ljs9uDMmTO/NNnzCghFpt988nHSBdy+166Fzz/9NPTm1K2Pn0yXuRu6+PzQm6Kifx8aSH+QD1pY+Pzzz0NvTt0qTv/y3s3Xhd4UFf38jdfSALjk2NCboqKRKy9NPs+HD60KvSkq+uT51WkL+rlnTPrYejIDapBcuPulC2R3tLa2/p27+VtjPcb9/Yp63iPrAt697PZAJc+TnagZ/lcb2rQANpZj53FHZlNyPB98m+u1tGQmB/z7HwjCUtsbNnxc6DgonQ5meN07wfnW685jDk8+y8/fXNcU9b1h6P1kNLP8J2qkZ6ih7629T8q+1r7/gmz6l/bgbDU80jtc6tLeMLhxQpb1ZAbUIEkLoO/3cIHvz6QVUK63tLS0yajjSp4nxZgWEq7HwhCWjePYe9NNUS76PtqbTf+iPKgl5D7Zc1lzTAcjy3Kl07/skrQ2N0t9d51xatrN+OAjDX1f7X1y6LW30kETB+8XnKmmS4NannhmQpZ+UwWKSrlc7hQXArd3Pq21tTVXyXMILTomADaW49ArzTHvl4/pX6pl6cPyw5V8rpPing6m/4Fs+pezTm+q+u678+70c11wXkPfV3ufbJbpX7b4XLdkq85ccvGELH1nCtTkaqaDWkgTABvLsXzmf1kiLvR21+reFSvUp3+plqUPp9PB/KSwfvcdCyO98U4H031+dkL+Pfc2VX2XpoNZuGdDp4PR3ic7Tzgmm/7l2eBMNV1aVnH/BeMuq0gARHWrmQ5qIU0AbDzH7mXZ2p+3rwy+3bW6mpn/fbL04a5TTkp/nB+NczqYdPqXdEqOkfaepqvvENPBaO6TspydLGvXDNO/jPn9HLxftuzlm+OyDJ0fUORqtoNaKIf+sW0WV8Nx4NEn0tGmLmiE3u5aPNzeV9Xanz5Z+rAE86Qba9nS4Kxr8eCL6fQvHYcfHJylD/csX97wZRU1OQ48nI6e7zrt5OAsvXw/V1yefj833TQuy9D5AVWoXC63Rz6ff8T5Nbnd1tb2g/JpW0Kp2Q5qodyMPxDWOUrXonQxysoT0uUYeturdf+9q9LzsM49KzhLH5au+cm6sSy797rr0h/gq68OztKHZQR9cp7mcUc17D01OXZfdEHaA3DHXcFZev1+jj1yXJah8wOqQC7oHecC31p3+ZPifH8ySEPuC71tzXZQC+Vm/IGIgaMMMkhHyz0dfNurte8VTSzsk6VurNfeCs67WncenU7/MvjciyZYantk8INN08F0DzXkPbU4JucA7zs/HT3/dmdwlt6+n+Kyl10DY7IMnR9QBXJBr0fWA86uf5jdvVXZ9WBqtoNaKDfjD0QMHEuj5S69JPi2V+PNpn/p8LOmsYV9UkZnJq00P7slOPNqPNyZTf/ifoBl/WkLLH24NB3MQ42ZDkaL49DL69Lu+cUHBGfo08U5QvtXPTAmy9D5AVUgWf3DXXxRrufz+Q/kUlbpqHSyZp9qxoNaCDfrD4R1jkPr3km7GQ/YJ6puxsHnX/I2/UutLH144Kl0VQOZ1yw082rcf/+D6fll7gfYCksfLk0Hc+H5DXk/LY5y3mLyH78rlwdn6NPSO5B8P+ecOSbL0PkBVSAX9G5yIfDE7HoSAN3to3O53IqwW0YA1HKz/kBY55h0BR24MO1mdGEw9PZX6t5rsulfrrnGDEsfltGZMkpTVjYY6R0Jzr1Sd593Tjb9y31mWPpwaTqYfec3ZDoYLY5y3mJxJaDQDL1+P539m7VEj2YZOj+gCiQrgbjA97y0+Dl/6twpt1tbW38/9LY140EthJv1ByIGjtL9G9uqE5umf3nJFEsf7jptSXqe5iOPB+deiZPpXxak078Mr+81xdKHOxYf2LDpYDQ4DncPZauz7JycJxean293HnNEFnZf2IJl6PyAKtdWslxbLpf7Zxf+/tzd3jr0Boma9aDWaDfzD4R1jrGtOlGa/mXv3by2uljZJ/tW3pl2Yy29MDj7Sjz44ivp+WVHHGKOpQ9LN2qjpoPR4Nj/4MNp9/yZpwVn1wiXuruXX7EFy9D5AUWuZj2oNdrN/ANhnWNsq05sOq/Hz/Qv9bD04eG3OtLAu99eUZynWZr+ZcXV5lj6cCOng9HgWFqd5e57g7NrhIdeeWPMZS8JgJEol8t9q62t7QHnDc6/yPxLuQy9bc16UGu0m/kHIgaOXacWV514IvhnmMwS/HxO/1IvSx/uOGT/bFWDN4Jvy2TuPPqwtMvt+bUmWWq7kdPB1MsxXZ1lXto9/253cHYN+X6SZS/3TuvnjXc3Yxk6P6AKlM/nX3Vh73wXBP/CXf+TcofetmY9qDXazfwDEQPHvpV3pK1qyy4K/hkm8mZze3ma/qVelj68aVWDm4Nvy0QuTf8i3fNDH5pk6cONmg6mXo6DazetzhKaWSPdc/Gy9DznW2/bjGXo/IAqkAt/H7uLrUJvx1hq5oNaI93sPxDWOZa6GRfZ7mYcePq5CWf3t8DS6+c+/ujg2zKR+1el0790Z9O/WGTp5XPffU/6uc87x+v71MuxfHWW0MwaaZnoPj3P+bjNWIbOD6gCyXQvLgT+MPR2jKVmPqg10s3+AxEDx03djGMvnm7BPZdc3LCJkS3tkyODxelgdmjYqhO1uKs48e6o7nlLLH04GZg0znQjmq6XY/nqLKGZNdIjAxs3TafUM1xiGTo/oAo0Z86c38vn82873+eC4JXlDr1tzXxQa6Sb/QciBo7WuxnTc3n2ys7lWW+apQ+XuhlXPRh8W8b8fko/sjskU41YZunD0iqdnEf79HPe3qMejpvPifeh+rZZd9dpJ6ffz0OPlliGzg+oArmgd6sLf+/IeYDu8tRyh962Zj+oNcpT4QfCOsfBYjdjAxe3r2r71r7W0OWrrO2TxdHPVqfvGHjsyS262ayy9GFplU6mG7nkYm/vUQ/HUjf1uX5Hz1t1adWWC84rsQydH1AFckHv32bNmvX10Nsxlpr9oNYoT4UfCOscNxtg0d4X/LOMdmn1jxUrzLP04WQC3912TFrZZOqe0Nsz2rIcWtI9v/IO8yx9eOjN9k3T9Xian7Iejl2nZCP9H34sOKsQllHPyfezz7zk+yEARqK2tra1c+bM+YPQ2zGWmv2g1ihPhR+IGDgW5wjru+Ou4J9ltIsrLshIxhhY+nDXkhNMrgoiXYql1T/GmF7EIksf7jjsoHQfffEVL69fK0c5703m+ZT5Pkf67M/16e37OeKQ9PtZ8zIBMBa5AHhIPp9f47xzLpf763KH3rapcFBrhKfKD4R1jjIPoMVVQeScv9Io5QasuarB0of77rwr7cZyQT30tpRbltlK9pujD4+GpQ/L2tQ+R9nWyrE4OlvOIw3NyMT3c80KAmAscsGvaxx3ht62qXBQa4Snyg+EdY7Jifx77pyeyN81EPzzFN2I86u0WfrwcHvvphP5Da3j2nPZJRMOILLI0odlPeB01Yn9vbx+zRO9lwYQPRCcUUhLy19xHkQCIKpbU+Gg1ghPlR+IGDh2n3Nm+mNxj52lomRgStL1+dSzUbH0y2J18G0Rb7bSwrp3x3yMVZZeWOy/IGPxjvrr18JRunyTpR7LpkCZqi5fCWVkfTcBMCbNnj17bktLy/fmOIXelqKmwkGtEZ4qPxAxcJTVDJLuolNOCv55xLLiR4hWL6v7ZN8tt6atocuWBt8WcWl1iUPHH51tlaUP91x+WdYaepP6a9fCUQZ9JPV88onB2ViwjAJO/oN7510EwBjkgt8f5vP5p5x/7TyUXT693XbbzQy9bVPloObbU+kHwjrHUovB7juamHRYFq1Pp684OzqWPjz8drZqy8J5DTsfciL3rrh60tHZVln68GTnQ9bjWjjKtC9J4Ln7nuBsLLgUiE9bQgCMQW1tbbc7L5s+ffpX5LZcugC41PmO0Ns2VQ5qvj2VfiBi4Fg6Z2jUig4hLAfqRqyz6oulD3cceaiZFR06Ds1WkHnp9ShZanuzEdHre1Rfu1qOIwPvF9bP3zmd2qnT79rZsXikdySdTsn9J/fFv/3bL4XOEGgSuaD3Xi6X++3y++bMmfM77v6NobapqKlyUPPtqfQDEQPH/vuzUYOnnxL086StkTsV1u++U3LgjpGlD/fecEPaDXzF5UG3Y+j1d9LWyP0XTLiGtGWWPlyaE/GOO1Vft1qOA48/lbZGnnBMcCaWLLMcCJd3d/6n/y90hkCTqK2traOlpaWt/D65zSjg5vFU+4GwznHTvGESvMLNG1bqrjm18ecjWt4nh15/u6Lg5du9N96YBtHLL4uWpQ8PPJquitK1RHc6pWo5loLo7SuDM7HkvttuzwLgjy8JnSHQJHIBcLGEPXe5Xy6X+1u5lFDorh8Wetum0kHNp6faD0QMHLtOzbpeH3w42OcpTkzdf1fjz1+yvE9K6JOpRibrevXtzqMWp13Rz66JlqWX76e0LrLuebTVcBwZ+qDQvmD3cSfnnsourtriAmDwRiRUgVzg29X5Iec3s8td3d1bhd6uqXRQ8+mp9gMRA8f+e1elrRhnnR7ksyTnL+29W7Cl6azvkzLZcCOXxhvt0tJaC/ZIznuLmaUPy5rN6dx7D6q9ZjUcS2t7H6M/GKUZ3LPsIloAUX2aagc1X56KPxDWOQ53DSYTQodae1ZaHpMfsBOPjZ6lD2+afsXPpMOTWboVk9HZF10QPUsflkmXtc+jrYajTJqedP/+7JbgLCyaiaAjUS6X+/GcOXP+SK63tLTk29ransjn84/K9dDbNtUOaj6LEZb2OJbWng2wgLycP5W0oNyv14ISkqW2N5uA+fW3G/7+ncceme4bjz8VPUsv34+MNs0mYNZaVadSjsmEx/vOT/eNN9uDs7BoAmAkcoGvfe7cuTOy63c7n+9C4ckuBD4cetum2kHNZzHC0h7HvjvvDjIH3/Dbncn7JpM/D2xsCpY+LKOAi2ubNvJ9S2sz77NHcq5ZM7D04eIcfH0rdUYDV8pRpgcqLnkWmoFVEwAjkQt6n8ilTP3iwt/HculubuPu/yDwphEAFYsRlvY4llbhmL9zQ7uBe6+7ruFr//pm6cNDL69Lg9iivRs6KXTvtddWNPo3JpY+PPDEM6rn4VXKsXvphd5WI2kWEwAjkQt9va2trTkX+P7eXX9c7pN5ASUMBt40AqBiMcLSJkdZQqqRk0In3VfF9VQDjnCNZZ+UVp5kJO7TzzXu+zlgn6q+n1hYqrOSSaEXzptwneRqXAlH+Y9aafJn5Ymom8kEwEjkgt4hzj8Xu+D3T3JfS0vL/3C3nwu9bVPxoOarGGFpk+PAQ4+mrRjHH92QzzDw1LOl7quQc9zFsk8W5zTrPu+chryfTPmSfD+HHVTx9xMLSx8urQ18zTV1v1YlHOU/aqHmzozJBMCIJAM+nFrKbzt/J+Q2iabqQc1HMcLSJseRwfdLS1sNvVF/K8Zk7j7nTBOT18ayT8oSX8nSVjJau2fY//dTnFy4itGlsbD0YWklTbrpD9in7m76SjjKqh+hBm7FZAIgqltT9aDmoxhhaZdjabDB1Vd53f5k6pnd06Xf5HozsvTh0trNd9/r9X02615s721KlurMZNLuxQek3fTPPF/Xa03GsTjBsUwALf9xC/3ZLZsAiOrWVD2o+ShGWNrlOPTaW+kPy77zJ530tx6X5pY756ymZenDxaXHZGoWn+/Tf/c9affiKdV1L8bE0oeL3fQS1Ot5nck4ymjwagbnTGUTAFHdmsoHNe1ihKVtjp1HH552LT32pJdtT1pKsgENAw0a0BCKpTo7WfarOO+bp4Ezyfdz2EHp9/PE003L0gs7WVt7z6zl9J2uml9nIo4jg24f2G+vdB94eV3wz2zdBEBUt6byQU27GGFpm2Op9Ud5gfuiB9e+lrYy7r+goVOahGDpw73X3+B1MMjg6ufTwR8H71f19xMbSx8ursxRz2kUE3GUJeca0QrcLCYAoro11Q9qmsUIS9sc5fwvmfjXVwtDz8XL0h/I664LztE3Sx8e7hworN9jp3TlCQ/Tf8iSZrUOzomNpQ+XTqOQtZNrnNx8PI5J6+wRhzD4o0qWofMDilxT/aCmWYywtM+xOEGz9sogyeCCvXatu4ssJpY+3L30ojREr9BdGSQZXJBMCL5LssTZVGDpw50nHZcO1rl3VU3PH49jqXX2wH1NtJ7HYAIgqlsc1PSKEZb2OcqapjLdyPrddkiWa9N6XZlSxNrcZTHuk5tamXZXXbmlOAq81sEFMbL04YFHn9g0h2INQW08jl2nLjExdVJMJgCiusVBTa8YYRkHx55LL1EdaTjSu6E0z+DgmpeDM2wkSx/uOvmEbP3ZO1ReT6Z7SUL/rtsnawBPJZbaltDXcej+aSvggw+rcBx6/Z103ey9dyuM9G0I/hljMQEQ1S0OanrFCMs4OA6/1ZF2B7pQIJMQ1/t6sl5p2vq3JDi/RrP04cHVL6StgAvnJeG63tcrnpspE0BPNZY+XFxZJxlMU+WUSmNx7Dr7jGxwydXBP1tMJgCiusVBTa8YYRkPx+7zz01DwdKL6nodOZ+sfe/d0ta/ta8F5xeCpQ8XuwTrXX5MWvyku18Gl/iavmSqOWkFPPLQtBXwnuom7h7NcfC5F9Ow72oo9MTpsZkAiOoWBzW9YoRlPByH3+3e1C1Yx7xzxUElMsI0NLtQLH04ORew2Epbx4jg4rJ8PcuvmLIsfXjgiWc2TXlUxYod5RwlSHYetTjt7r/t9uCfKTYTAFHd4qCmV4ywjItj7403luYdk2koqn3+0Otvp9OWSIg0OHFt7Ptk99IL01baiy6o6fmDL76Snlu21651ty7FzlLbUi9SN0kr7fXX18Sx/777N3UlD34Q/DPFZgIgqlsc1PSKEZZxcRwZeL/QfuDCtCtr1YPVPXfow1LrRc+VVwbnFpqlDw+v3zR4o9qVVeTcQQkWSUC56eYpz9KHk4nPd9sx6WIfXPtqVRxHugdLq374Wpmn2U0ARHWLg5peMcIyPo4DjzxeaiWS0YiVPq/YeigjIiVIhuZmgaUPF9dWbt9nXhIIK31e9wXnpa27xx2lsvZzM7D04eLqLR2HLKpo2h7h9/lnn5VGesuazLW0vmMCIFIQBzW9YoRlfBzlx6d72UWlrqjh7qFJn5OcuL77jknL1OCLlbV8TAWWvr6f4ijRzuOPrijM9T/wUGlaEa1JuZuBpZfvR1rCjzki7ap3dTRZmBN+G2+5oXT+oKz+EvozxGoCINpC+Xx+fktLy/cqfTwHNb1ihGWcHOX8o84TjklDxknHT3g+0uDTz6XdkoaWfLPE0sv30zNc6Dho37S7/eKlE05AnKwokX0/mkuKNQtLH05WWdlz5+z7WTbh9zPwYBbO99jJ3Kj52EwAROXaNpfLLXQBcE1bW9sPKn0SBzW9YoRlvBylJaL9gH1KLU1jdTcm3cUy6CM572+5+a6rZtonZZCNLOOWdBuedfoWLbXyXciUJOv3+En6/Vyle15mM7H04cFn16RLIcr3c+bpW6wVLC2Fci5mMrI7WUruvuDbHLsJgGgLufB3FQEwTDHCMm6OQ2+8Wxo4IK1IPZdcnIxU7Ft5Z6FryfHp/dLyd+215sNfaJY+LC1G7fvskZ0TuEehZ/nyZPBO3623FTqPPnzT93PNCvXvp9lY+rCE9PaFe6bfz357JXUi3fES/DoWH5B+Py4AfvToQ3BUMAEQbaFaAuDGjenOhGu3MIRl/BxHeoYKPRddUGqpKLesTNF/76rgjGJh6eX7ae8tdJ1xyhbfggRPdgAAEoBJREFUTfGcssEnnoJlQA+/3VE6nWK0OxYfWBh64UU4KlkY+swSKELVEgARQpvr34cGCx+suqcwctXlhQ3XXlX45LlnCp/94hehNwtl+lV/b+H9O28vjCy/tPDeTdcV/nXN84XPP/009GYhp88//7zwi3ffLry/8pb0+7n5usLP171W+Pw3vwm9aU0nn1kCGVM+n/++C3fPOq8us9y+rfgYWgDD/W8MlnC0ZFjC0prhqMvST9JA0YpzAMOdjwFLOFoyLGFpzXDUZekzS6DIlMvlFrjwt875anf9ryp5DsWoV4ywhKMlwxKW1gxHXZaeIwVqdlGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyADCmXyy1wntfW1nb93LlzZ1fyHIpRrxhhCUdLhiUsrRmOuix9ZwoUiVpbW3/k/O3s+t+5EHh3Jc+jGPWKEZZwtGRYwtKa4ajL0m+qQNHIBb5FuVzuQrnuLr/lbr9SyfMoRr1ihCUcLRmWsLRmOOqy9JsqUEzapqWl5WtyJesGPqOSJ0kxbtyY7ky4dgtDWMLRkmEJS2uGoy5Lv5ECRadp06Z91YW/22fMmPHlSh5fQAghhFB08p0nkCHl8/nvu3D3rPPqMsvt27KHbOWuL5k1a9bXK31N2Yn435jO/8ZgCUdLhiUsrRmOuiw9RQ0Uo1xA3HPu3Lkz5LoLgv9QyXOkGGVnCn0+Q+wWhrCEoyXDEpbWDEddln4TBYpGMvLXBcBPXPDbkPmqSp5HMeoVIyzhaMmwhKU1w1GXpe9cgZpcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/IAiF8WoV4ywhKMlwxKW1gxHXZah8wOKXBSjXjHCEo6WDEtYWjMcdVmGzg8oclGMesUISzhaMixhac1w1GUZOj+gyEUx6hUjLOFoybCEpTXDUZdl6PyAIhfFqFeMsISjJcMSltYMR12WofMDilwUo14xwhKOlgxLWFozHHVZhs4PKHJRjHrFCEs4WjIsYWnNcNRlGTo/oMhFMeoVIyzhaMmwhKU1w1GXZej8gCIXxahXjLCEoyXDEpbWDEddlqHzA4pcFKNeMcISjpYMS1haMxx1WYbODyhyUYx6xQhLOFoyLGFpzXDUZRk6P6DIRTHqFSMs4WjJsISlNcNRl2Xo/ICMKJfL7dTW1vaPzufn8/n/VenzKEa9YoQlHC0ZlrC0ZjjqsvSZKVAkmj179lwX+l6V662trf/TXV9T6XMpRr1ihCUcLRmWsLRmOOqy9JcqUFSaNWvW1+Wyra3tqFwud2ylz6MY9YoRlnC0ZFjC0prhqMvSX6JAsemLra2t/+IC4HJ3fdtKnyTFuHFjujPh2i0MYQlHS4YlLK0ZjrosPeYJFKPy+fz2zneE3g6EEEIIIVSnXKj7fltb27POq8sst28rf1xLS4u7q+3zmTNnTgu1rQghhBBCyLNcONzThb5b5Lq7/IFzv7u6deDNQgghhBBCvjR37twZLvTtmnX/Xt7S0vKd0NuEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCaFLlcrkFzvPa2tqun+NUdv9h7r5/cD7JXf9mwE2MSvl8fn5LS8v3Rt33J+5im+nTp3+ltbU1F2jTotJYHNkn6xP7Ye1i39MT+2H9Gn18ZP9EVcsV34+cv51d/zu389wt190O9Bcyl6Bcd5ffGL3SCBpT2zpuCx2vNTIRd/kf3O2X3f0bnVeyOsukGpMj+2T9Yj+sTex7umI/rEtbHB/ZP1FNcjvKIrfzXCjX3eW33O1X5LrbiY6UVsGyx/WF2sbY5FhdNToAOp47h9qeWDWaI/tk/WI/rE3se7piP6xf5cdH9k9Uq7ZpaWn5mlzJuoHPkOvu8gLnHYoPctd7pbk+1EbGpHEC4GnS2uouj5gzZ84fhdq2mDSaI/tk/WI/rE3se7piP6xf5cdH9k9Ul6ZNm/ZVt9PcPmPGjC/LbVeYS10g/HHx7+724MyZM78Ubgvj0VgB0Gkr+Sfj/GyAzYpOY7QAsk/WL/bDGsS+py72wzo1qgWQ/RONLbczfF+KzHl1mZ8tO09gK3d9yaxZs75e9hxpUt697PZAwzfcoCpguUVwkXMr3fPOzm5u7f7284ZvuDHVwpF9cnKNw1V8W7YfnpM9lP2wCrHv6YnjoY7G6AJm/0TVy+0se86dO3eGXJdRRNl9fyb/q5DrLS0t7u62u0JuY0waIwD+d8fwu3Ldcf7P7m8Phtu6eDRGAGSfrEPsh7WLfU9P7Ic6GhUA2T9R9cr+N/aJ22E2ZL6q+Df3P4pT3N+2z87XYKh+BZIpdRzDdc5Xu+t/VXb/PPkfmrv/REa9Ta4JOLJP1iH2w9rFvqcn9sP6NNbxkf0TIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIoTiVz+d3qXRprlwud5x77I21vI977l+69xqq5bkIIYQQQkhRWQBcXcljswB4Qy3vkwXAwVqeixBCCCGEFEUARAghhBCqUi4QHeLcmy2v2O6Czo/L/rbYucP97T13efvs2bP/sPg3d19X9ty17vq/uctb58yZ83vu+Svc9Y/dfa+6698qPl7W7nb33eT+NuzcI2FsvG1yj7vDPebSsu041/mBcR67WQB0t8+W15fP4/xi+drMWQC8zd1/bfZ5Xy//+7Rp077qbl/i3Cdhzz3+Qnf3ttlzCYAIIYQQil8tLS15F3Z+XlyHU0KaC3F/JNfd/bu6wNMpC7W78PPb7vYyd/up4nMlADqvcY//g1mzZn3dXX/H+W33uB+6P2/lLs8vC21y+3lZR9Vd/6I8R4Kje909xtqub3zjG//J/b3f/f1/u9f8fyU0yraN9djRAdBd30G2x13d2l1f5Dzi3u935G8SAN3jf+3u21H+7q7v7K5/6D7j17Ln3ua8fMaMGV92j/1d9/dV7vZJ2XMJgAghhBCKXy7QtEgAdJd/XwxJRbn7H3Ler3h7+vTpX5HwNHv27LnZcyUA7lz2+PPd7fuKt11g+gt334bssX/mPFD++u7vP3H3PTLetkmQlOdLa5x77N9O8Bkm7AJ2f//APf9Ps/eUALhm1Pu8JIHQ/W26fD4Jf2XP/b60gGbPJQAihBBCqDnkgs0/uZDzuHTbOt8trYJyv7v+5ujgJaNg3d+/l13vcn//67K/neqec2XZ7T9xt3+Rvcc/u9ufShgTS6ub80fu+msTbNrWWaviWxNt/xhdwAfLtmfvIf5N1ipZ6gIe9fyV7r5D3ef6rrv8rLiN2XZ+JFyy5xIAEUIIIdRckhbArNv2Cbk9Xguge9wcuV1NAHSXfy7dydVsj3vtY2V6F2mhc9cPHO9x5QFQWuycN7rH/3HZ3z8obuc4LYBrpQVQupjd5a/cXduMsz0EQIQQQgjFL2ntc/4fco6fu7mNuzzZhZxH5W9yDqB0f8o5gBIO3f1LnZ8uPrfCAPjL7ObW2TmAR8+cOfNL7vZWct5h+QCMcmWB8X3pbpaBJNKS5x7/7bEeWx4A3WN+JK2U2WCVbd39R0nL46gA+Gvn7bPP+1N5bRm8kr2vnAO4rHjbvd527jF/kz2XAIgQQgih+OXC3Xdc4HkuG7Ur3Z4PF7uAnbZyoecwabmTVjUZmbvddtvNLD5X7q+0BVDkwtTvywhhORcw65pdWz7iuCg5B8/9bb0Eu+J90hKZdRdvO/rxo7qApdv48uzzyPscUr6dWRfwre6+a7JRwOsk2BVfS1o5s3MZu7Pu33Xu+r7ZcwmACCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghhBBCCCGEEEIIIYQQQgghZFn/P0GpiyOcWviYAAAAAElFTkSuQmCC\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# We can also force the range of the axis\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=False,\n",
|
|
" xrange=(-20, 10),\n",
|
|
" yrange=(-3.0, 3.0)) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
" \n",
|
|
"# Or equivalently\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=False) as figure:\n",
|
|
" figure.xrange = (-20, 10)\n",
|
|
" figure.yrange = (-3.0, 3.0)\n",
|
|
" figure.plot(np.sin, (-10, 10), label=\"sin\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Passing extra arguments to matplotlib plot command is as easy as\n",
|
|
"# passing them to replot plot command.\n",
|
|
"with replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=True) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10), linewidth=20)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# You can also tweak the palette used, either with a palette name\n",
|
|
"with replot.Figure(palette=\"dark\") as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10))\n",
|
|
"\n",
|
|
"# or by explicitly passing it a seaborn palette\n",
|
|
"with replot.Figure(palette=replot.sns.color_palette(\"husl\", 2)) as figure:\n",
|
|
" figure.plot(np.sin, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# It is not mandatory at all to use a with statement\n",
|
|
"fig = replot.Figure(xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\")\n",
|
|
"fig.plot(np.sin, (-10, 10), label=\"sin\")\n",
|
|
"fig.show() # But in this case, we must show the figure"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## One-liner plotting\n",
|
|
"\n",
|
|
"You can also make plot with a one-liner."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Many plots done with a single one-liner\n",
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, (-10, 10), {\"linewidth\": 10}), ([-i for i in range(5)], {\"linewidth\": 10})],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Another one-liner plot example\n",
|
|
"replot.plot([range(10), (np.sin, (-5, 5)), (lambda x: np.sin(x) + 4, (-10, 10), {\"linewidth\": 10}), (lambda x: np.sin(x) - 4, (-10, 10), {\"linewidth\": 10}), ([-i for i in range(5)], {\"linewidth\": 10})],\n",
|
|
" xlabel=\"some x label\",\n",
|
|
" ylabel=\"some y label\",\n",
|
|
" title=\"A title for the figure\",\n",
|
|
" legend=\"best\",\n",
|
|
" palette=\"dark\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Using subplots"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Subplots are defined by `group`. You can declare a group and add figure to it using the `group` keyword in `plot` commands, as demonstrated below.\n",
|
|
"\n",
|
|
"_Note_: Groups are represented by one unicode character. \"\\_\" is the default group in which go all the plots which are not mapped onto a group. Hence, it is a reserved group symbol which cannot be used."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Using groups to define subplots\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Applying a grid on a figure, one empty subplot\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.set_grid([\"ab\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 73,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Applying a grid on a figure, one empty subplot\n",
|
|
"# Note that if there is a single row, enclosing in a list is not mandatory\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.set_grid(\"ab\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Applying a grid on a figure, default group is masked\n",
|
|
"# Note that if we do not put the default group (\"_\") in the grid,\n",
|
|
"# it will not be shown\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.set_grid([\"a\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Using set_grid, you can define very easily (and visually) a quite complex grid layout\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"c\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"d\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"e\")\n",
|
|
" figure.set_grid([\"aaa\",\n",
|
|
" \"bbc\",\n",
|
|
" \"dec\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# By setting the grid to False, you can ignore the groups you defined\n",
|
|
"# and plot everything in the same subplot.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\")\n",
|
|
" figure.set_grid(False)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Forcing a grid layout\n",
|
|
"# Use auto={\"ignore_groups\": True} to put every plot in\n",
|
|
"# a different subplot, regardless of their group.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.set_grid(ignore_groups=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Auto gridifying example\n",
|
|
"# Use ignore_groups=True to put every plot in a different subplot,\n",
|
|
"# without having to deal with groups.\n",
|
|
"# Note that ignore_groups=True will discard the groups you may have defined.\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"c\")\n",
|
|
" figure.set_grid(ignore_groups=True)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Gridify example\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.plot(np.sin, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAG4CAYAAADVDFZ+AAAgAElEQVR4nOy9SZAcR5YlWNk9MoeS6jolL6w6ZHLrvvWpS6REZkZKuufShxEpqZnKToJMkMRK7AQBYt/3HSCIHcS+kwCxAyRAkFgIgNj31T3cIzx8iQABMjMrs7IyWUmMfVUzdYeHm7mZmqp+1eB/Ip/EEjCzb6r6TPXr1/f/4i8IBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgfCjxCuvvNLvhRde+D+ifuall14a/fLLL/+TZ9O9X/+tqWcjEAh2gniDQCAQ3MX/7pHyII/IL3kE/X+F/ZD3M3/v/cxa+LX3/7/xfnaPuUckEAiWgXiDQCAQugM8Yt4QReQeeY/zyLxPzc+3m3kyAoFgK4g3CAQCwXE0I3Lv75Z69mrN7wvPPffcX5l5On142PMX//fDN35xMdPzFyce9vh/X8B+HpvwoOcv3si88b8Knn304NX/56fYz2MRfuL1l8kPe/6vu56t+PIf/uF/w34gLPxYeQPaHNoe+kDmV/88yfujn2A/ky3I/PM/PwecAdwBHIL9PDYh88Y/vsi+Nd4358Fr/9//wH4eAoEhxkp+ubeS/0XN78vPP//8Xza77g8//PDUVvyps+Npy9tvPvWIilnr6Hee/vmPf8R+LCvwr/fuiPcCVlo8D/uRrMF3x448826++Wg79iNFQhVHNIIu3gDYzB3Q5rV9APoEgaO0aO4z7wa4hPCUfVtaRw0T7wW+PfANshkqOILgAGJu5fSq+X0pznWhEz1+/Nun33xjn7WtWMYnfvNnP20ZO4L9unjocOx/D37Z7J+sPXr0m6e5CWPY+yhsWPe0ZVAf9uvKhcvoz6bakrbho8qTp1n/fRQ2bXya6fWaZz2eduZL6L6E+aeCH8KgizcAto6tzlyRtTm0PesDXl+APgF9Q1e/c8UqX1/m72Ng76ff7NjCfg1cApyC/WyqLWkbwreFTfy8b01+3mz267aVy9H9iPIvLT8QHEE9kXuk/WLt33vE/Xewmodfv/DCC96PvnwgznVhgEBnevTILussPHqa6dvzaebNXz7teNj6tPTlaT44x4yIfQ3wy1b/0ljl+l1O4sMGeB+1b59+e+QAnygvXYL+bKotaRsWjx7jH7WpE9nvW5csYr9v/+hjdF/C/FPLFM9CF28AbB1b0NZsPLy/mP0+N2UCXzx6fUNXv3PF4J2w8fDx7qc/fP894xC2eLxxF/3ZVFuSNuzs/A37trDdlJNn2DcHvj2Zfj3ZtwjblzD/1DEFwVp4pD3AI+bbnm30fv0P3h/9xPt11vv1X9f93CyPzH/p2ZwXX3zxpTjXtpXkikc/Y4MxP2cmH6Adv36aHdKf/VnHg7xyAnDJClv4yr1t/Xrm2/ffPuFk1f/Np53lb9GfT6UlbcP8wnn8Y/8p/9iXz19KvHAw7Z8OzvD5QBtvAGwdW8GHHNoefh8sClq9vqGr37lgneUnjCOAKzpbCsy/wvp1PFrucQr286m2JG3YcT/HF9VD+7NvDfwZfHuSLhxM+6eaMwg/MthKcsFKtXjoSPXP/GgOTA5VE4BL1jJqOP/AXb4hfMxNGc9Xr6fPoT+fSku6ig+2fzuyBf5nsHAY0Iv/WUsR3Z9G/mFzgCxsHFsd2Xb+IR/QW3zIOzIFfxu4L+sjqvudKwbcwKLjUyYI/yqXr/MFkscp2M+n2pK0YfHIp89Ejdmf+VvCtX9mk7nMHQRLYCPJsQ/54H78o/2wtTogDxziA3L5MuUE4Ip1QH6Tn8MD7ynwsX3XLr6S37gB/RlVWpI2rNx+yD9mI4Y88+etdVFBm8xlErdxbIlo36L5z/w59Am21XnnofJ+54q1bVjPOWLnLuHfo85fs8ky49pcCf0ZVVqSNmxd/gHniIOHxJ/BThPj2iH9Yi8cTPuHzQEEx2EjyVVu3uMf8pHDnv3z2w/8Px+qnABcsdKJk3xrfN7sZ3ysXLzCV/eTxqE/o0pLtIo/2HiBIP582VJ0fxr5h80BsrBxbLV+8L7/IT/87J+LD/zhWNfpjtwB3MB2Di5cfca/4MADcAv2M6q0JG0oFgi3n10gwLeG/fmt++j+NPIPmwMIjsNGkhPh+LoPNosMDgy2+NqVEoAr1vbhWpHEXesjnHDM9PZPvJYeoz+nKku0ig/SBupSBIC8bc0DdJnEbRxbLaPf9T/YD57580ZbfKr6nQsGnMBORnscAbmAtf4Bl7Cc4nUfoj+nSovbhpAuEpwUr4/0wTcoSdqRaf+wOYDgOGwkOSAiNsn5ZG+Xv8sv4BpWpeNfKCMAlyw3cazI/6v3McgDLF+8iv6cqixuG7LFgX+isf6QUGflu+rk2LJDMi6TuG1jix1yeAsmOa+zNq/9O5HkDyfnFfY7VwyifkH+X71/ZT8P8Me6e1A8foLvqjQ4JNS+5xN/crwO3Z9G/mFzAMFx2EhyuelTnjnF98yA9CaFbECuWaWMAFwxmORk+r3BT/H5Ub5aH+GdsNXqgUOoz6nSYq/im3zgc+NH8cjQ9TvoPtX7h80BsrBtbFWu3eYTGa+t6/8uaoGQpt+5Yu37D/q8ubqLf53Fb6oqAhbmusla3DZsW70qNOAQqAjkZ0xB96eRf9gcQHActpEc3+blScmdrZUuf1+5eiuU5GUJwBULkpJrDzk8s5Wzn+sBtq1dg/6sqiz2Kv4YX8W3LlnY8O/FVs6RT9F9qvcPmwNkYdvYEtu8yz9o3AcWL+R9wOsrqvqdKwYTPzbJ8SaCjfxreXdwl0N3rlvcNhSLQ28BUf938A3ih+66bg9jm8vcQbAEtpGckGwIieSwXJZAoLPJgOxuJF46ffaZAyD1PpZ9lX+IoGI/qyqL24aFrVv9E447G/69iBxblufkMonbNrZEfmyDSA7rIzt28D7i9RVV/c4Vy02f7B8AudLQv/zcWd1ORipOG/JdlZ7+rsqThj8jIse+tJQt5jJ3ECyBbSQnJjm+AHTDATl8EB+QmegB2d1IPKhwUNi0qaGPHcFqdVBf9GdVZXHbsHXxgsiTjMFWjm2TY5dJ3LaxJSY5DVJHwIIT9BAJVNXvXLFAHzPYVan3LyiZZ2vFHBmL04YdmTa+qzJ8cOjP5OfMsHJy7DJ3ECyBbSQn9Ow2bwr9mfzs6Zzoz11ITQAuGZR6Y1tYnx0P9VHoJ+bL6M+rwuK2YcvYkQ1PfwZW3crpbdVWjsskbtPYYqkjA8JTR8DEafBx7ynrdy5YR74k9OzC/AONTDY5/uB99OdVZXHasHz2Ag84zJ4R+jOw4GaT410foftU7x82BxAch20kF+TpRJ3yFVs9+/anJgCXrNFBhi5bOTP8AzRfX0Z/XhUWaxun49dPM31+9TTz1quRp3xt3MpxmcRtGlvNUkdYP2GnhF9lfSWoEpKm37li1YMMU0P9EwdoJoxGf15VFqcN2/fub5oaEpwSDssvxvQPmwMIjsM2kmsZ9U5Txf6gIkhwoi0NAbhiYpJTl6tS7yMcAOGT4wPoz6zCYm3jBIdjmgiEB7U9bdrKcZnEbRpbInVk7qzInwsEf5udBO5O3AELZcaX3sI5zD/gFJZb3bdn08mxKxanDYVywsFw5QRRYciycnkucwfBEthEcp2Vb2Ot0IPDDrUrWlkCcMU67rc0nOR02crxq16AtAH2M6uwOG1YOnMu1sdfbOVYlOfkMonbNLZEfmxE6giYOOxw5nzqfueKta1a2aUKSiP/xOT4fg79mVVYnDaMs2PCFt+9X+c7DHX6ktj+YXMAwXHYRHId91pirbREPdwmoq7dicRLJ8/wSc78OZE+ggg028qZNgn9mVVYrG2cQKx1w/rIaxUPH+U/530Qsf2q9Q+bA2Rh09gSkxyvjSN/bv36yJPCSfqdK5abOtEXiL8W6Z8oCXfqK/RnVmFx2jA79G0+6W1SBznYmYKFOLZftf5hcwDBcdhEcuWvvm56AhiMJXy//RZP+G5/lIoAXLHq4ZjNkT52tnUI3SrsZ1ZhsbZxVq6I9fEXuVCzpqP7VesfNgfIwqaxlZ85LfIEcGDFQ0diLQK6E3cIXVWPG6L8g+ipjYcdZK1ZG3YWHnGuHNCr6cGw4CQwHBrB9qvWP2wOIDgOm0hObF/GEDIOCpuDMLQsAbhkrSuWNaxJ2chHkIFhhF/oRH/utBanDSHaWR/haGTVXMFh6H7V+ofNAbKwaWxBakQcIeO4EfLuwh1iQVgnDdXIP+AWxr8rlqM/twpr1oaiqECMEniBkHbtNjq2ucwdBEtgE8kVNvpaVHs+afqzorJDjSRKUgJwySDfsVbINcrH3MQxfHJ84y76c6e1WNs4gfRNiPxHYCyXp1cPz16zJtHdZRK3ZWzxdvVrPTdpV5BHqpdEke13Lljl+l0+yZk4tql/Ird6ZnRutSvWrA2F9I33LWl2rfbde3wN1o3oftX6h80BBMdhE8m1LvLFfL883XxA7vqID8gtW6QJwCUTCdp1EY5GPrYums/f48kz6M+d1ppv43Qm2vIW7zHThu5b4B82B8jClrEFY6K+RGKUQV9pFiHvLtwBXMomOR63NvMv7ml6V6xZG8K3I+6Wd+kL/z0uXqD0GdP6h80BBMdhE8nlJsSPXIFOIBuQS5dIE4Arxk+hvfY081bXCEcjH+EwBCO2vfvQnz2tNd3GuRFEOMbEul5YJBXTP2wOkIUtYytp5ErwzM170v3OFQtKIBY2bmjqH5xwBY6BE682iaXLWrM2DIT1S59/2fRa1UhqPJ4x5R82BxAch00kJ5KVIw52BFa+fL1pLk93IXEQLmZRruGDYvkodL/WrUN/9rTWrA3hxCJbCCycF+t6kN/EUgeOfIruW+AfNgfIwpaxBW3J+vvKeLlrea+v8NOuZ6X7nSsGAseNdEHD/Mu+M9AXS29Hf/a01qwNRe7w5RtNryUOjFh0uM5l7iBYAltILukACyZFLe+G13DsLiRevnQtdLLbyEf4sLGISMxJkc3WrA3hw5ZksitOU2/diu5b4B82B8jClrEFbZnk9KqYFO0/IN3vXLH8grm++Pmzk90w/6qTouvoz57WmrUh1P9NMtlNEqAw5R82BxAchy0kJ0LsE+KF2OMk9HcXEi8e+zw0WbmRj7C1xd7l+FHoz57WmubxBAeHmui6iXcZlHWKSB0w7R82B8jClrHV+v7ipuUjay3QjYxK6O8u3CHKR966H8s/qAXMIuTHTqA/e1qLakOZA2FQJs+mw3UucwfBEthCcjJJts1WcN2FxKOiVg1zedrt266QtaZ5PEv82tFfnIp1vfKVm3xyPGUCum+Bf9gcIAtbxlZuyvimklC1VjpxknPNkkXS/c4VE1Gr4jex/EsaTbXZotowzg5SvSU5pGjKP2wOIDgOW0guzqq83prlcHQXEhdCxw3y1kJzeQY0Jn7XrGkeT8KPv5ABGfo2um+Bf9gcIAtbxlZ2aP9YMkCBCf23iEVAd+CO6kKwd2z/bKyWI2tRbRgnh7zeksiUmfIPmwMIjsMWkpMR2mx2iqs7kDgYVK4Iq3IQmssTsvXjmjVrQygHyD7++ehSToHB6cZM/zdZ4fvO8hMr/MPmAFnYMLY6S09Y+0Obxj25CmW/2MTonYHS/c4Fi0oFCfOvfO4izx+ebU+1HFmLasM4KhL1lqRQgSn/sDmA4DhsITko/5a01A6URWMrso93JyYAl6zlvaAOZdci7WE+5uc3Tv52zSLzeJhsxatPM31+lUi2omXMCD45vvPQCv+wOUAWNoytyu2HfCtv7MjY/4YtAnq/zvpOd84fFofBFsyN7R/UumXvc9Q76M+f1qLaEL4ZzXRk602UKp07C923wD9sDiA4DltIrvpRzsT+N81WZN2BxNnHypvgsIhV5dvYPobJP7hmkXk8gQBwwtJuQOC21PV0mcRtGFuyH+VmpeO6A3dEyUGF+QccA1yTdFFlo0W1IXwzku44wYIx6WJDt3/YHEBwHLaQnFDnT5CzVjpzjpP//DmJCcAVE9tVwwYk8jFMANY1i8zjucDruoK4c5JripzKurrKWP5hc4AsbBhbQgMwYc5afsYUvgi4eDVxv3PFhCB8gxPyUf4lTauw1aJ8zM+bzXdIzpyPfT2RUznIjsN1LnMHwRLYQHKQixXk8ST5d5VbDyLlTroDiZev3OA+Tp2YyMewElCuWVQbQh1o5uPyDxJds7BtO58c79xlhX/YHCALG8ZWYedO3pbbtyf6d6KW+LHPE/c7VyyqJGSUf3A4hk2Or9xE9yGNRfnYMu49vuN0+0Gia7L8YQhUlLvuxmD4h80BBMdhA8mJGpQJ806ayZ10BxJvJlkR5mPl2m0+cZw0Dt2HNBaZxxPI42zbluiaxUNHeNRozWor/MPmAFnYMLba1qziE7nDRxP9u2ZyJ92BO2Dss0mOxwVJ/AOuYRNHj3uwfUhjkVHOEHmcZibysb1vlg3+YXMAwXHYQHKwDcO38qYk/rfZAb34QC49TkQArhjU82WTlQ3rQ0mgYTJ3rtj0pKMLFpnHs2ql1Me/dDpIHeiaHI/hHzYHyMKGsQXpH3wr71yifyfkTlavStzvXDFR1i3XdSs3clytD2qJ70f3IY2F5jl6kz7GjQO6yuM0s9z0IHXgmhX+YXMAwXHYQHIg4yJbnQEScsNOdHYHEi9s2hSpPRVKcqB0zwq7v+Z0MndkHk9wcvxcssMc1cLuY63wD5sDZGHD2MpNHCNVnQEOAEUdHnGdO9jhsV6vMQ5odNI5MrK+ew+PrG/ehO5HGgvdHQlOjo97L/E1RdWZEOkx0/5hcwDBcdhAcjIi0IGJE51ffR2bAFwykat0vHFppshtjqFvJxLItdEi83gkTo6DCTHokIM1pv3D5gBZ2DC2ZPu4ONHp9aGk/c4Fa9bHI3Nrj/nlEhuUnnTJQvOjU8i5JC09qds/bA4gOA4bSE6cVtu7L/m/jTjR6TqJg+VnTuMT3K8vh5JAaDJ3ULvy5j10P2QtOo8n+clxMK4DFx4dMe0fNgfIAnts8Sj3q1JR7mYnOl3nDiECHVJbPfJ0vcc1bII0y20x6DAfZU+Og9mkruAydxAsgQ0kJ8LqEknHUcncrpM4mIhy3c2GkkDoFmlEdNQVi9Qrg5Pj/d6Qum52+CA/P6qI7h82B8gCe2x1tPA8V6gJLvPvM/16+vqa38Xud66YiHLNmx3a78L8g4h6VHTUFQuVyJI8PMbea3Aoz/tm2eAfNgcQHIcNJFet6Xs98b8tHvDFoD9cG5sAXLJmp9Uik7kjagi7YqGHXDJtvgj0UKnr5iaPDz0hado/bA6QBfbYqtb0HS/171tGDOGLgEwhdr9zxZpFuaL8a6au4IqF+QjfCi4CfSjxNcuXrvE+N32yFf5hcwDBcdhAclDJIUqVP8qE3t3ihbEJwBUDralm+ohRPsIKl0dH8fXuZC00kTv4+IfoIzaz1oXzeNT51Ffo/mFzgCywxxbo23Gty/lS/z7Qu4O+FLffuWKgccmjXI31EZv5B5F1tvBsUH3IFQvzsXXxglB9xGYmJMveS1Z9SJd/2BxAcBw2kFx1KyY52ZQv+0LJ0ybFJgBXTJQ6iyCbyGTug4cjS+W5YKGJ3Ck//iIKcCB5FEC1f9gcIAvssdW+/2Bo9D+ORS0CXOcO0Lhk/ftQ41JnzfxLsyi3xcJ8hEUjF7q+kfiaaVNPVPuHzQEEx4FNcp2FIBm7r9S/j5okuU7isCUeNrmN4yN82NgkyfvQYfsia6GJ3Cknt+0ffcwjJFu3ovuHzQGywB5bhS1beITba0uZfy/qwTaYJLnOHXkxuT0b2u+i/Kum5SSfJNliYT6mndzCwSEWHfW+Xdj+YXMAwXFgkxyU4pHVZAKL2iZ1ncRLX5zyq4B03d6O46PYJp0slyNlg4X5l7acW7WM3DJ0/7A5QBbYYwtKALIJnNeWMv8+qoyc69wRVQUkjn+QUsMmkF+cRvdF1sJ8TFvOrVpGrqv2rGn/sDmA4DiwSQ5EfNlptTkzpa8Biu6NqoG4TuLt+w7wKNf6dZEkEOZjR7Y91SlJGyw0kTuoAiJ5wKV8/hLvd7NnoPuHzQGywB5b+dnTeZTKa0uZfx9VDcR17hCn3Fsan3Jv5l/bunU8urr/ALovstbIR1EFZGDyKiCB5efM8AXoL6L7h80BBMeBTXKg38dIeOVy6Wu0jBrOye5+S1MCcMkKmzdzEv54dyQJhJ7mA520N3/5NNPnV85WAwnzT7YEWGC2SF24TOLYY6uZRFIziyoJ6DJ3cJ3L15lGYpjOZTP/gHNYdHTLFnR/ZK2Rjx33Wvi4H/2u9HXbViz3tWePofuHzQEEx4FNcmk0mQILq8/oMomDiS2uY59HkkCUj9kh/Xl0tK0D3R8ZC03kDra4rt+Rum5V6kI+EqDKP2wOkAX22GomkdTMYHuUpUh4fSluv3PBOlsrvG8P7R/Z76L8syVFIo018jFN3fnAqtqzuOoKLnMHwRJgk5yK05hhQtIukzgYbE822+Jqmsw9fhSfKN16gO6PjIX5p0LIuSp10VUI2KR/2BwgC8yxpeI0ZpSQtMvcUbl1n09svbEf1e+i/BMpEnNwUyTSWCMfVQg5R2nPmvYPmwMIjgOb5OCAQ9pkY8iRYyuyffubEoBL1jJ2JJ+8RdS6beajqAZy9gK6PzLWMI8nxhZXrPf77mA+icy2o/qHzQGywBxbHdkCn7yNGCJ9jagUCZe5oxyj1m0z/0StZMnDeTZYIx/b9+7386rXS1+3ejhvEbp/2BxAcBzYJBe2fZvEwvJVXCZxMJDGYRGq9nC5gabJ3Jbkq8hawwlgWwff4hoSvsUVx9JuI6vyD5sDZIE5tqK2b5NYdkg/X9Kjs2m/c8Xi5FU380/Icw3uh+6PrDXyUeRV794jfV0V28iq/MPmAILjwCY5SMZlUZh7LdLXCMtXcZnEYVuSRSf69WxKAlE+RtVKdsEa+ZdWOigwqJPKos+ItZJdJnHMsVU6c94/wDEn1XXCJD1c5g4Y6800LuP4l+kbXivZBWvkY1rpIDA4dEQHyAjdAtgkFyfK1czgOH4jKRmXSTzuFlfT03xBtYR1H6L7JGMNE7kV5SeJ6OineNFRl0kcc2xBRDutegBYWJ6ty9wR5FXD2I/qd838E7WSEVMk0lgjH4WEi6R0EJgt0VGXuYNgCVATuRXJlMABh0ZJzy6TeOX63VhbXM18VJH0jGmN/KtGfD9Ide04Mjsm/MPmAFlgji1VMiWty5Y2PGnvMneEHYpL6p9IkbhxF90nGWvkYzXiK38oTlUOsgr/sDmA4DhQE7lzJb6SemdgquuEyR64TOIikXve7KYkEHma78IVfp2Z09B9krGGidy79/CP/+ZNqa7dvncfv87GDaj+YXOALDDHVtuG9Xzyvnd/qusUNm3i19nzSdN+54rlZ07lUa4LVyP7XTP/ghSJ7nSATJUsFnyzWHQ0X0L1D5sDCI4DNZH75j0e5ZowJtV1+IrsNW9F1uOZFZnLJC6iXCuidbi6+2m+Rv6p+vgXj5/g73jZUlT/sDlAFphjq/WD93mU6/gXqa4TtghwmTtUqAewd7x8Wep8OUyr95HtOL31KovepRXGz00Y7ctr3Uf1D5sDCI4Dk+RUlIELLDtsQJcVmcskDhGJOFGupqf5RHT0bXSfZKxhIvfSJfzj//mXqa5tQzk4l0kcc2ylLQMXGEwg2SLA61PN+p0rBjshzaJccfwT0dFP9qL7JGP1PqracQKzoRycy9xBsASoidzHPleSywXWSPDYZRKPS75NJ4AQHX2rx9NMr9ecLAfXMJFb0cc/LHfUtH/YHCALzLElxnuKXC6wsEWAq9zBxnuvHsyixnsc/+IuQm21eh/jCGTHtWru6AlU/7A5gOA4UBO5vckNI5hNG1NfKz/LnxR8fTmUAFyyuNsvcXx0uRxcI/+qk/102y8d+TKPCAwbgOofNgfIAnNsiYh/ayXVdappKKOb9jsXTGhkRpSBi+tf3DQUW63ex+pkf3rqaxc2bkSPjrrMHQRLgElysLJslIAtY422BV0lcbC4Cdix5BzGjOATprtZdL+SWsNEbkUJ2CpzgtL4h80BssAaW2E5vzIWti3oKndA3h/L+R07smm/a+Zf3INotlq9j/BtaLTdL2PVg2ibUf3D5gCC40BN5FaYZNy2zi8Ht/9AKAG4ZHElGGKd5pvhnwq8GH4q0FZr5B/IBjGBWgUSDGGVIEz6h80BskCbACqqBMOuFUhR9X1WcN1V7oCTv/zU/9Sm/a6Zf3GlqGy1eh/b9x3wy8CtS31tG6KjLnMHwRKgJnIrrFPbvmsXX5Ft2x5KAC5Z3Dq1sU7zLVnEo6NfnEL3K6l1OclX/IZ//Af2UfOekaOjLpM41tiKG+WKa9mBvfkioPQ4tN+5YnF1P+P4p6LeMqbV+1jYtk1ZVSQboqMucwfBEqAmck8cq0xotHjoCF/drVkdSgAuWab/m/yj1KQMUxwfg8oAxYOH0P1Kal1O8j3I84/SqHeUXB87OuoyiWONrbhRrrjW8t47fLHl9a2wfueKFQ8c4jzojflm/a6Zf52VbzG02kYAACAASURBVNm1gIuw/ZKxeh/b1qziPHj4aOpr2xAddZk7CJYANZF7+CBOvLli6muVTp7hK9/FC0IJwBXrLD3hUa4BvWORQDMfCzt38ujojh3oviW1LoncV25y4p06Ucn141RN0O0fNgfIAmtsqa5uA32JLUSv3grtd65YYft2PtZ37mra7+L4lx3Qiy9Ey0/QfUtq9T62LlrAx7r3rUh77Y6WIl+IDh+M6h82BxAcBybJiWLjCnK5ypeu8YnB9CmhBOCKdTxs5eTy3rBYJND0NN+hwzwqsHYNum9JrUsi9+mzPPqzcJ6S60ONZJ47Gl43Vbd/2BwgC6yxBXm+rD+vS5/LBZZfMJdPDE6fC+13rhjsgLAo16EjTftdHP9aRg7ji3SPk7B9S2r1PuamT+bR/svXU18bdmZY7mi/nqmvlcY/bA4gOA60RG7FuVyQw8UmTWNGhBKAKwaRiLhRrjg+lr487UdHF6L7ltTq/Sse+ZR//FetVHL9Rrmjpv3D5gBZYI0tlblcYG0rV/BJ09HPQvudKwY7IHGiXHH9y02ZwKOj126j+5bU6n1sGf0un8zea1FyfZE76n3LsPzD5gCC48AiuY77LXzC5g1KFdeDU5xsQjm4XygBuGIQiWBRrgVzY5FAMx8bRUddsS4n+T76mE/YtmxRcn3IB2ITytWr0PzD5gBZYI0tmPyzCZu3GFBxPehLbEL58e7QfueKxY1yxfUvP9+Pjp45p+wZTVm9j9lBff0T/4+UXL9l1HA+obyfQ/MPmwMIjgMtkdsjKD4pmazkelwB39cG8zXdXCXxJFGuWKf57qmdbJu0Loncog7wPiXXL53iW8qtiraUZfzD5gBZYI0t2P7nW7ZnlVxPCNLX1AN2lTtElOt+dJQrrn+NoqOuWK2PVc1PdRWRctMm+ZPtG2j+YXMAwXGgJXIHhzYWLVB2TVED068O4CqJQySCfZC2bo1FAk1P87U/6hIddcW6JHIrLsFUvnKDL0Q8MsfyD5sDZIE1toJDG3AgSMX1RElKr2+F9TtXTES5mmxLxvWvUXTUFav1sUNDTfTWRfP5QuTUV2j+YXMAwXFgkZzqXC4w0AVj+Sp3HnYhAGwySmLVKNf+WCTQdALIKie8zlbAKg7cmLR6//JzZvKP/7n02pFg2NFRl0kca2zFjXLFNdAhZSkXc2eF9jsXTIha9/lVrH4Xxz+ItNdHR12xWh8rtx/ycT7uPWXXV52KIOMfNgcQHAfaSb4gyqUolwsMdMHY5ODC1S4EgE1GSaz1g/f5yvL4F7FIII6PonZqvozuXxLrcpJv4hg+yb95T8n1VVaVkPUPmwNkgTW2VFdvAR1SFgWeODa037lgUBqxUVm7sH4Xx7/i8RNdoqOuWK2P5QtXfO3IacquD2Xg2EJ99x40/7A5gOA40E7ybVJXBziw+ooXLpI4WH7ODD6RPX8pFgnEOs03fhSfON1+gO5fEutykm+4XyGlJb12JBiLjr7VQ2luUFL/sDlAFhhjq1Gub1qDajssOvRuVdPNRe6o3HrAJ7ITRsfqd3H8Aw5iE6c5M9H9S2q1PqrWjgSDbxcLYmzehOYfNgcQHAfaSb6Vy/3k4mPqrllX8cJFEgcDAmeTtVv3Y5FArNN8s6fzSeXXl9H9S2L1/mX6vRGrQkoSyw7qgybn4DKJo0wAg3zWQX3VXbNBxQsXuUNM1mbPiNXv4vgHkXY+qRyD7l9Sq/UxboWUJAYHY9g1V65A8w+bAwiOo7uc5AODShe1FS9cJHEwEeWKUSElro/YFS9k7ZmTfOWgQkovte+7QSkwk/5hc4AsMMaW6lKAgWXffuuZihcucoeIci1dEqvfxfFPVLx4F6/ihazV+ii+DTt3qnvfpCBAcB1oJ/mEXpW6I/QQ+atd5blI4mBx6wAn8bEaHT2M7l8Se+YkX1AhZWTzCilJLDdlPJrYrcskjjG2oI1YRGrKBKXXbRk5lC8CMm1d+h32GIhr9fzXrN/F8U9ER70JMrZ/Sa3WR6iCpJr/qlJmOPqqLnMHwRKgneQbM4J/dO9mlV0Tcv/YimzJoi4EgE1GcY2VGHojfgH22HIO27YrrZ5gyp45ySc+/uOV3iM/bzZfjJxVc7I4qX/YHCALjLFV/uprvs3ptZnK6+YmP7sIcJE7RFWb7c2r2iTxT6RdOKwg0LpkoZ8fflrZ9St3MnxBOnYkmn/YHEBwHGgn+Ya+/YxmnwqD07/8pNfULgSATUZxrSPnn+QbPig2CcTxsX3ffh4d2LAe3cck9kwi95nzvH3nz1F6D6EteFyNtmBS/7A5QBYYYwv0H3WcSg0WASVvglnf77DHQFxrW+/LR+07EKvfxfUPThVzBYESuo9JrNbH/AxfIeLiVWXXF9qCwwag+YfNAQTHgUVyoFUFmlUqV5Wg/1er9eQiicMpXRblGj8qNgnE8VGI3S7/AN3HJPZMIvenx/gkdsVypfdoW78u9odTh3/YHCALjLElFjLr1S5kWlcs44uAz4536XfYYyC2DwlE0pP4B3zKFQQeovuYxGp9rGrEZpRdP4nuoi7/sDmA4DhQTvKVHvOV08DeSq8LGne1OlgukjisUGujmHFIII6PpWDrTHH0TLfV+idKdm3aqPQehZ3xt850+IfNAbLAGFvVVIZdaq+7ceMzJQZd5A6RyuBHMZv1u7j+VaNn19B9TGK1PgodVIU7TmDZAb35TlbpCYp/2BxAcBwoJ/k0JfOLFVm/nl0IAJuM4pookbc4Xom82HIOV2/xyOLUieg+JrFnTvJt3aqlLFWS5Hkd/mFzgCwwxpaOZH6w9o8+5osAv/yii9wBB2NYlMsb63H6XVz/oFwn2x73uAnbxyRW62Omb0/lO05g9YeHTPuHzQEEx4Fyku/6HT4ZmTRO+bWrcg7fOkniokTe6lWxSSCOjx33c6glz2TtmZN8a1bzj//ho0rvoUMkNol/2BwgC4yxpUvOqHjoCB933gSzvt9hj4G41jJqeGw5oyT+YZc8k7XAx0cVPfJRYPANY5Pu63dR/MPmAILjQDnJd+4i346sqb2pykCvKqgU4SKJJy2RF1vOodDplzzrh+5jEnv2JF9Q6UXdST6warWD5gK6OvzD5gBZYIwtEDnWIWguFAT8RYCL3JEdHJTIexSr38X1D7vkmawFPna2+JVeRgxRfg9RmzxG1SYd/mFzAMFxYJBc6fMvYwuWJrVqFY0HTpI4lBVKUiIv9gQQueSZrD1zkk9TNRNR7aCmFqxJ/7A5QBYYY0t1LejAoE/VVtFwjTtEibxe8UrkJfGvWvJsM7qfSSzwsePWfW3VTOAbxhal3jcNwz9sDiA4DpSTfPsP8u2WdR8qv3Z+lj9JuHDVORIHg7JCvETeZ7FJIK6PmCXPZK3WP10f/45sQVuEII5/2BwgC4yxBW3EIvzZdqXXrV8EuMYdSUvkJfFPpKWsWonuZxILfKxcvOJP7qcrv4cQ2D9wCMU/bA4gOA6Uk3x1JdtUmhD8/PK0cyTOnn/RfP78p+KVyEsk5xCUPHvYiu5nXHtGykHTx19Xibm4/mFzgCwwxlZtjq/K69YvAlzjjqQl8pL4Vzr1Fd+xWRTvYJotFvhY9r4FtQUCVJqOEnNJ/MPmAIIBvPTSS6Nffvnlf/Jsuvfrvw37uVdeeeW/ev/7j88999xfvfjiiy/FuTbKSb51H/Jtzv0H1V97zSpxUMA1EgeDskIsgnkpnuRCEh/rqx24YM9IOXgTNP7xVy+5oOuUYBz/lBFFHXTyBsD02Ko/5a/02qVgEdC7S7/DHgNxLGmVnCT+gfwLi6DNwCl5JmuBj/AtYBHMNauV36N9/wF/N2sdin9KiIJgLzzi/nuPoNfCr73//41H5nvCftb7u2vezzz2bO/zzz//0zjXRznJpzFvAg5PBFIhrpE4mBBdjSlYmkjPa+4sPrk8Z77kmayJk3yd/se/r/qPP5jQCcuXjfuniitqoZs3AKbHFlSiqNX5VG214vSucQeUMUxSIi+Jf/UC+65Y4KM4WOdL/Ki00vEveHTxg/dR/FPBFQSL4ZHyOI/M+wS/98i6PeJneya9PspJvuDk1LmLyq9dTVje5ByJgyUVLE2k5+WRFJt4e6SF7WdcEyf52vSWXapOvM1WO9BF4rp5A2B6bEElCp0TEVGesq3DOe6AMoZJSuQl8a9eYN8VC3wUB+s+2av8HrCY1qVoEcc/mXFLcAgecS/17NWa3xdgq6bRz3pEPufFF1/8n97/x/7sZz/7L3GuDwPk8WPemUxZoJ3UceOO8muXgnJhq1YwvzD8S2OwvQVRCIh4xfn5JD4W/JJnxQMH0f2Ma4F/nfez/OM/doSW+8D2FpsAXrpm3D9VXFEL3bwBMD22KpeqVXJ0XL9lzAjOS/eyznFH0d+KhDEet9/F9U9E3/u9ge5nEgt8bFu1nC98Pzum/B6V6/7W++RxKP6p4AqCxfBIebm3kv9Fze/Lzz///F+G/PhP4D8//elP/5NH+OfjXP8pAlpHc8HS7588Vn7t313nH4nK8sXKr60bP3z/PZ/kDOyt5fpPDvDoKPzfNfyhJcMnr3Omabl+ZTlPS/jdtStarh8FBTTRBbp5A2D6Pf3uGpdqqax4X8v1oW/B9f/QktVyfZ14st8f2wf3arl+y0Cefwsc5Roqy7h4+O9uXFV+7T89/oZHXscMV37tOEhJEwTb4W/l9Kr5fanRz3kr+H/0/m6h/9v/4BH57+NcHzqR6VUu1ACGQfOo/Fj9iuxyNWHZtVV8rWBpklVgXB8h8pckSmCDBf5VvjrHiXbhPC33aVvNqx2Ujn5q3D8FNNEFunkDYHpslWqq5Oi4fuuCuTw1xetrrnFHwT9YB2UN4/a7JP4FAvuduSK6r3Et8FFE9y9fV36PRyU+AcwO7IPiX0qaINgOj5z/Dlbz8OsXXnjB4+eXD8CvPXJ/sfbnPCL/797f/zf49c9//vP/7P3csTjXhwHCOrKhvAVxkq/Pr7RcvzZhGfwy7V+qZxdaZPEFS5P4iJmwLGuBf6XPjvOP/4rlWu4jDg8ZrnYA/qnmDIBu3gCYHltJq+QktdYVy/gkyutrrnFH0oN1Sf0DEWUusH8f3de4FviYS3iwLqller/+NPPWq8YF9nVxB8EyeKQ9yyPzX/q5OiDT8BOPqLPen/913c/1gVW/93fTbD0F3NnqJ/MPfVvL9WsTll0j8Wo1gviCpUl8xExYlrXAv+Levfzjv3GjlvvUHh4y7Z8W0vgLvbwBMD22CpuSVclJfP2NG/j19+5zjjuqJ/zjHaxL6l9VYP8Kuq9xLfAx6cG6pJYd2l8cHjLtn3LSIPy4YJrkKnf9ZP4xI7Rcn0UYvesHCcsukXh9PdK4JBDXR6EVNjmeVpgNFvjXvm0r/zh/9LGW+0DlFRZhXLnCuH/YHCAL02OrbeVyv0rOMS3Xh77FFgHbtjnHHcHBusr1O7H7XRL/dNXh1mmBj8HBOl0an8HhIfi2mfYPmwMIjsM0yZUvX+eTkOmTtd0j41cLeNTxrVMkXjx0mE9C1q5JRAJxfYQKIGzy/d4wdF+T+gfvhH38Dx3Rch+ovBLkGJr2D5sDZGF6bOW9tmGTkNPxquQktdrx59oEsGXksERVfpL6ByLKOsefDgPfgoN1UEFG131y0ybx6OjlG8b9w+YAguMwTXLBhzav8UPbMryasOwSiddGIJKQQFwfoQYwI8NBfdB9TeofREV5BOKUlvuYWJiE+YfNAbIwPbZ0f2hLJ06KCLxrE0A4hMA4L2ad76T+gYiyzgi8DgPfvv/1d3zR++5gbffJ+4eHdC1MovzD5gCC4zBNcrB9w7fa9CTzg+UmjOar4TsPnCLx2hykJCQQewLY+Zunmd6vPc281cN4wrKsBf7lZ8/gH/+vL2u5j0hNGDvSuH/YHCAL02NL91Zb+fwlvjidM8OpCSAb12+9yg4jJOl3SfwDEWWdObg6DHz7Y6nIF3YT4h+sS2pwMI1FRz/Vk5oQ5R82BxAch/GTfEGy/SZ9yfb5mVzPq3LxqjMkDlZ7CjEJCSTxMTukH48UFDrR/U3iH5yMZm16856W+4jDSZoqjUT5h80BsjA9tmordei4fuXGXf8U/li3JoDe+2B9d0j/RP0uiX9FzafwdRj49q8PuLICHGLRdZ/Cpo3aKo008w+bAwiOw/hJvppavbru0bp4IY8WnTzjDImD5ef7WwlnzicigSQ+tox+l0dH77eg+5vEP9BGZM+dLWi5j255oij/sDlAFqbHFqvVq1FuoyNT4FHgkUOdmgB23Gvhz+2N7ST9Lol/pTNchxO2O7H9TeLj767yqG7rkoXa7qNbnijKP2wOIDgO4yf5VnHB3eKRT/XdY/UqPpHy7uEKiYOJHKcrNxORQBIfc1Mn8kja1Vvo/ibxLzuAi4d3lp5ou1cgUK7zHo38w+YAWZgcW52lx0JwV/89ejs1AQS+YJFLjz+S9Lsk/pWv3Eh8D2wD335z+kseuVyzStt9ioePCoFy0/5hcwDBcZgmudZFC/jk7OQZbfcQUcY9e5whcTCZ6FxiPa/5cxJHGTGNneT785+NROcg8sPef6bNqH/YHCALk2NLnGAfqfcEO4sy+rW4XeEOEZ2bHz86l5Q3RJRRk3yXDgPfvj16iEfntm7V9/69bxmLMi5eYNw/bA4gOA7jUg5+WZ7yxWva7lEr6usKiYPJCIom1vNa7ucZHvsc3d+4/v377/5Fq3h4YFUttbtG/cPmAFmYHFugb8ciUF4b6byPGIOFDme4I8jPgxziJP0uiX8iz1DzGFRp4Nvjj3doz88rX+T15/Mzphr3D5sDCI7D+Em+oCzP7Yfa7iFEfVetdIbEwWRKCiXW89qw3j9pvB/d37j+/amzYiT6kJ8zM1E1BVX+YXOALEyOLVNVbIKTxhCFd4U7QDWAn9DdkKjfJZoABieNDefIpjHwrXPjWq3i4WCV2w84P3nfNtP+YXMAwXEYP8kXlOXJl7Tdo3TqKxGSd4XEZXOcEss57PrI1xrcju5zXP/+0JI1kn+UtJ6qKv+wOUAWJseWqTrWQR5u5epNZ7gDdEOTavTJ5DhWc2Qfo/sc18fKcl8/9JQ+jb6OXIlz9zsDjfuHzQEEx2H8JJ/msjxgsL3MogUzpzpD4rJVOhLLORxMXm0E09hJvpvXjZxAbFv3IY8WHDhk1D9sDpCFybHVvv8g77fr1mm9T3ASv/zVeWe4o1ol53CifpfUP1FtxGCObBoD34rzfP3QS/pSjjorXGwayo+a9g+bAwiOw+hJvvK32svygFXuPOQRo3HvOUPikHcmk+OUWM6hptoBts9x/fvtuTOJc5xkrLCD5wsVdu406h82B8jC5Ngy1TZBjmzp2HFnuEOmSo7MBFDkyN4wlyObxsC3wiReFKByJ6P1XkH5UfjGmfQPmwMIjsPoSb6sr7M1Yoje++R5SL7lnYHOkDjkncnkOCWWcwiqHcyege5zXP++O340cY6TjJmKMtX7h80BsjA5tkxFZ4Mc2eK+/c5wR3729MRVcmQmgCJH1uMQbJ/j+ph/d5CfclTWei8oNcd1StuN+ofNAQTHYfQk3817vtK+vrI8YCIk3/9NZ0gc8s5YlGvpksQkkMTHahuMRfc5rn9P9u1OnOOUqg0055nV+4fNAbIwObZM5WcGObLt27c7wx0yVXJkJoCiDU6cRPc5ro9Z7xvAInMaU45YG0zQW6kozD9sDiA4DqMn+QxGnzL+wP/h+++dIHGIbPDo04eJSSCRnlfGTBRWlTG/tm5MnOMkY6ZOmtb7h80BsjDJHaZOaAc5soUP1zozAZSpkiMzAWz70D9Re9Bcjmwq6zCTcgQmE4VNay5zB8ESGD3JZzD/rGU4D8n/+29+4wSJQ24T+/Ds2JGYBBLJOZSecFIc0Avd57j+daxeZiTyYEprrt4/bA6QhUnuMKXRKDhq6RJnJoBZkX8Wv4KNzASwsH27n4e5C93nONaZK/LF7ruDtd+rdcki49FRl7mDYAlMkhysHE2dQM2NH8Xu9cdS0QkSb1u/jm897T+QmASStmFQ7UD3togKA79KC+cYyT0yVW2i3j9sDpCFSe4wVaVF7FLMmeHEBFDUsO7bM3G/S+pf+74DnL/Xr0f3O451+Pp8uQmjtd9LnMQ+qHeXor4NsTmA4DiMSjns2mVMgw4kYOBe//rwvvUkDta6bClfQR7/IjEJJNbzCrQYWyvofsfxrzBtgpHThybqzTbyD5sDZGGSO0zVaa49je/CBBAON7A+643ppP0uqX/F4yd4dNTjKmy/Y7VlUKFj1jTt9xJajLs+Muafy9xBsARGT/Kt96tQ7NNfhQJEoOFev7t22XoSB8vPm82jXGcvJCaBxHpefrWDyt0sut9x/Gsd/Y4f/Ymf4yRrLDqasBpLWv+wOUAWprhDRLkMVKGACGMQBXZhAgjyJux5x45M3O+S+lf+6ms+ofK4CtvvWM8b1OhdslD7vaCyEouObjAXHXWZOwiWwOhJPj/KVTx2Qvu92lavYvf6zVenrCdxsNyU8XxSdu12YhJIrOc1fTKfbF6+ju53HP9aBvcxVoEAap2yeyWox5zWP2wOkIWxCWBrRSrKJXWvmiiwCxNAEDhmEcvpUxL3u6T+ATexe02ZgO53HCsd+ZRPytas0n4vqK3OJpvLPzDmn8vcQbAERk/yBVEubyWp+16FLVvYvb779JD1JA7WMsqPcj3IJyaBxHpeC+fx7ebT+sojKbNOc9Ef1g6Go6Muk7gp7oC2kIlyyVpQk/uHH36wnjugxBmbeHhjOmm/S9p+wE2sHUYNR/c7jrXv5vJRha1b9LcDQnTUZe4gWAKjJ/kko1xSg3/PJ+xej3fvtJ7EwbKD+vLIU/GbxCSQWM5h5XIeidVYIF2VdRY6eERmaH8j96tGR28YuZ/LJG6KOyBSLRPlkrXskP5cQeD3v7eeO4pHP+NRrpUrEve7pO3X2f6Ij8XB/dD9jmOFzZs4z33yifZ7Va7eMh4ddZk7CJbA6Ek+b+XIolz3c9rvVfTD/482rbOexCHfLNOrh2evJc49k5Jz2MR19do/2YvuezPruN/Cow5jRhi5n4iOnjln5H4uk7gp7iidPsejKwmjXLLWMvpddr8/Peq0njuChW5h06bE/S7xBDAFT2FY26qVfCx/+pn2e8E3jfGU13dM+ecydxAsgdGTfP7K2kR+VenUVzzauOJ960m8s+CvrIckX1lLyTl87G+NbNG/NZLWKldv8o//tElG7hfUgoWcHhP3c5nETXFH8bPjfJtTcy3owHJTJ7L7/SHfYj13BKkuMKaT9juZ9oPoH+Pw9kfovjez4CBg2UCqC3zTTO5UBG2IzQEEx2FyAmhSf658kSdHF+fNsJ7E0+TWSMk5HD5qLDk6dTt+xaM/rQvmGrlf9aT6ASP3c5nETXEHqAaYPGGZn891J39/67r13BEcdoMxnbTfybSfbK4yhuVnTOFBgMvXtN/L5En12jbE5gCC4zB2kq9stgJF5fZDHuWaPNZ6Ehf5I1MnSpFA0jYsfXmaT6oW65dHSGulYzz602Yo+iMqsnj/N3E/l0ncFHdAdRyTFSjgJCfc77fnz1rPHUGUq3TyTOJ+J9N+kONmKo87reXGvccnq3cfGrlftSLLt0bu5zJ3ECyBKRLvaPHL8gzXX5aH3S9X4luHI4dYT+Jp9LWk9LwuXOH3m6lfIDWtFf3oT8FQ9Md0tQOXSdwUd8hWyZG/H48C//rzz6znjkDwvnzhauJ+J9N+snqlGNbyzkA+IWstGblfdvggPuHMFY3cz2XuIFgCY1IOQVme8aOMDI7Oynd8wumtymwncdBFlFXYl9LzumW2LdJYu19/tP0jMwr7VT0vMxFHl0ncFHcEETkT+qGsz/kVi57s32M9dwQlL2FMJ+13Mu0ntFyPm2mLNJbp/yY/CNhppuRlix9xhN0nE/dzmTsIlsCYlIMvWAp5GcYJoOM74+STxCCywaNO66RIILGeV7adT44NFElPa4UP1/IPziEzNTbh9C/rp4ZyDl0mcVPckZ8/1z+Zfd5ImwQ1yx9t32T9BBB2VFjUqSVZ1El2Ati2LojGHkT3Pco6K99yjhvQy5zM2fQpRgX2XeYOgiUwJ+Vw1qiUA1iLH5LvzJvZApA1yG1i25w7dkiRQGI5h1KQj9kb3fdm1rp0Mf/4f3HSyP1Ma865TOKmuMO0NmPp8y/5pGrNcusngJBTzfPOktVIlp0AFoKI/C4z+ZiyBtuwplOAYNHIBfZJQorgCLqrlANYsD3SccdMSF7W4HQjP3mavEayLJEH1Q5s1/PKz5nBP/7nLxm5X+UOPzwE2zkm7ucyiZviDrG1didjpE3K5y7yD/miuVZPANOcPJXljaDmbWHjBnT/oyxIOSpMMXcIUEhIed86E/dzmTsIlqC7SjmABQnSlUv6ZQBSEccKeeKQ1vMa4ut5FTrR/Y+y3KRxfBJ/866R+wWHhyCh28T9XCZxU9yR9ZP5OwxF8ivX7/IF2fSJdk8AA+25Icm152R5I1jIt61Yju5/lJUvXuWcOn+msTYkCSmCczAv5WBGXgNMCIGe+so4ASV6zhS1eaX1vN5zQ8+rZeQwPlHNthm5X5A7BJIOJu7nMomb4o5MIK9RMSOv0fGwle9WjBlu9QSwqh/6jlS/k2k/UXt40Xx0/yOf8+QZvvhfaa4QgPjGSaTyyJjL3EGwBMakHNaZlXJg9zRYCiiNBYKlZYlIpbSelx9Zq1y/g+5/lGUH9uEJ+aVkNZLTWKZvT2OC5S6TuAnuENuc/Xoaa3+ox83yQIf0s3oCCFp87Dknj5fqdzLtFwjs52dMRfc/yjBKgVYlpJIf5pMxl7mDYAmMSTkE8gGGpBzAqsXA7a55K6QcJOQDpPW8DOfWyRirPfpWj6eZ3q95vzeXq5gd+jaPOBkoWegyiRuZALZWeER22ACz/Y7VYV2WUAAAIABJREFUvO1htN8ltSBXMT9nplS/k2k/03JeshbUSH68e6exCWBVQuoDI/dzmTsIlsC8lIOZE1KMBD76mEcdt20zTkBJDORYZKQcAhKQ0vNassg/XXsK3f8ww4rEQEF31h73c9rv5TKJm+COjvstfJvTaxOTfS87yHzkOamVTpzkE473F0v1O5n2ExJSI4ag+x9lha1b2XN+e+SAMe6A078kIUVwCsakHKZNMirlAAbacSwn48O1xgkoiVWlHJLnOEnrea2RqyFq0kQu1mizuVgmy125TOImuCNNmcQ01jJyqNHcUxkrHjrCtxzXrJbqdzLtVy3pabeEVNvaNew5f3PyhDHuqEpITTZyP5e5g2AJjEk5jB1pVMoBrHSC63m1frDEOAHFtbRFxKX1vLZs4dHR3XvQ30GYVW7w05iFaROMTgDzc2fxxco5/eWuXCZxE9wBJcdYVEWiTGIay00c458+v2e838e19o938/HhjWWZfifbfsBVtktItS5dwt7Nv1y6YIw7SEKK4ByMSznkzIkywwcc4+ORxECGRVbKISABKT2vFB8PY+339WW+Tb1wttEJYPDxgC023fdymcRNcEcgygxtYrLv5WdN5wvWi1eM9/u4Vti8WXoRl2YCWJWQeoT+DkLbz1/E/f7OLWPcEYhPk4QUwRkYk3Lwy7KZknIAq1zD2T5KRBpCymG4NAlI6XkdPupvH61CfwdhVvrytHEpB7Bg+8hE+TmXSdwEdxQP8jSONsNpHEJC6uQZ4/0+dj9dLZ/GkWYCCLIztktIBWkc/9aaM8YdgYRUhiSkCK7AmJQDDAyDUg5gIoF8zLvGCSiuCSmHKcmlHAISkNLz+uKUdAK5KcOQcgALEsjhEJHue7lM4ia4IzjIVTB8kEtISB391Hi/j2vVg1ynpfqdbPuB7IztElLBQa4/Peo0yh0kIUVwCt1VyoHdtw3nvkkMZFhkpRwCEpDS8xL3nYH+DsIMQ8qh9r4gI6T7Xi6TuAnuKGziUk7thqWcXJCQys+Wl3JKMwF0QUIqkHL699/9zih3kIQUwSkYkXK4hyPl8KjTvIhsUksj5RCQgJSel7d6Z5HHSePQ30GYYUg5gAWRR4gC6b6XyyRugjuCSFzxqFkx96qE1Fbj/T6uVcXck5dJTDMBBK6yXUIqiMT98Oc/I0lItWi/l8vcQbAE3VnKAfxqCSRWDOYeJjEh5bB2jbSPUnpeKcpImTIMKQewoIxU6+KF2u/lMomb4I4gF69kOBcvkJBq+1BuXJowUc7xYatUv5NtP5CdsVlCqraco6kc98CEhJT3zdN9L5e5g2AJurOUA/iVH+GLLBsqJJ/U0p7GldbzEqeP+6G/gzDDkHIAC04f52dP134vl0ncBHcEp3HLF8yexnVBQio7WP40bpoJoO0SUqA0wRa3wwcZnwCShBTBKXRnKQfwqzBptHH9wSQmpBz2fCLto9QEkJVZe/Vppvfr6O8gzDCkHMAqN+/xiPXEsdrv5TKJm+COQI+vYliPryohNct4v49rUCJRVo8vzQQQJn42S0gFeny5ce8ZnwAKCSnvm6f7Xi5zB8ESmJFyOIQi5QB+FedMM16BJIkJKYcjcqcNU+l5DejNIwilJ+jvoZHByWjTUg5gHZk2HkEYOUz7vVwmcRPcEVTk6MgUjPY9ISE1ZYLxfh/HYMyyCP5AuYocaXjDdgmpoCJHfsYU4xNAISF1kCSkCA6gO0s5gF/lpQv5isxgDeIklkbKIfBRWs8rqEGcbUd/Dw2fb9RwFCmHoAYx1IPVfS+XSdwEd2QH8pq80CYm+x5WDeLYz5ct8OeTrMmbhjdsl5AKavK2LphrfAJIElIEp2BGymEjipQD+NW5zo+wHTthnIjimJBy+PqytI/Sel7jR/HttVsP0N9DI8sO7Y8i5cC2x3v18Ow17eWuXCZx3dxhsh263DuQkBr6Nlr/j7LKrfs8QjlhtHS/k20/2yWkisc+5xHKFcuMTwCFhNQmkpAiOAAjUg4rV6BIOYBf3+zwE5b3HzBORHFMSDncSC7lEPgorec1YyqffF68hv4eGhmrOYog5QAG0T8TkSeXSVz7BFBEYvua73+BhFRfOyWkyhev8knYzKnS/U62/UB2xmYJqfZ9B/gkbMN64xNAkpAiOIXuLOUAfj3Z76/Idu40TkRxLI2UQ+CjtJ7Xwnm8XU6dRX8P9dZZxpNyYO0ics/atN7HZRLX3S4wJkzlYjZqF5slpEqnvuLbnIvmS/sn2362S0gVduzgi/6dO4xzB0lIEZyCESmHmdNQpBzAr19//hlfkXmrQdNEFMeElEO7XGH1VHpeK5bzyOynx9DfQ70FhdUxpBzATJ0+dZnEdbeLydPYjdpFSEjl7JOQKh49xnlt5XJp/2TbD2RnbJaQalu/nvPa/gPGuUNISM0iCSmCAzAi5TABR8oB/PrteX+lvGKZcSKKY1zKoYd0jlMqPa+NG/hKee9+9PdQb5XbeFIOYKb051wmcd3tYlKPsVG7VCWkHhq/fzNr37uP72xs3Cjtn/QE0HIJqdbly/jOxrHPjXNHddEyRvu9XOYOgiXozlIO4Nfvbvi5MgvnGSeiZpZWyiHwUXoCuHMX/4hs347+LuqtfOkampQDmKm0BZdJXHe7lL48bWw7rVG7VCWkrhu/fzMrbNvOF2+7dkn7l6b9bJaQyi+Yy9vtzDnj3EESUgSn0J2lHMCvP2QeiomEaSJqShYppRwCH6UFXfcf5NtI6z5Efxf1hinlAGaqBq3LJK67XUwm1DdqF5slpEBTlfXPA4ek/UvTfsBZtkpI5aZP4ZFbb+JumjtIQorgFIxIObyFI+UAfv2xzMsCgeQJBhlFWVXKQX67IJWg6/ETfJK1bCn6u+jybJ8dR5NyAAMZBxPSRS6TuO52EZIam/VLajRql6qE1OfG79/MYMyyyenxL6T9S9N+ID9jq4RUy7j3+OT07kPzE0AhXSSf1pOkDbE5gOA4urOUA/j1/a+/8w8TDEYhoyhLK+UQ+CjbhqUz5/n9589Bfxf11r5vP5qUA7t/IF6+davW+7hM4rrbxaSobqN2ERJS+w4Yv38zg7rqbAL41dfS/qVpP5slpLLDB/Edp1wRhTtIQorgDLq7lMMP33/PJ6ADehm/fzOrSjksSOWjbBuWr9zgEchpk9DfRb1hSjmAQSknFoHUXL7QZRLX3S6irNYh/WW1GrWLzRJSuakT+QTsyk1p/9K0H8jP2CohBdJR8GyPOr4lCSkCIQrapRxu3EWVcgAEgsKdHb82/gxRllbKodZHKUHXu1k+OR87Ev1d1Fvb+nVoUg5gUMydTc6XLtF6H5dJXHe7wLtnk4wTJ433v2ckpNbbJyHVMmYE34L1xrCsf2naz1YJKeD4QMA7rY+yRhJSBGfQ3aUcANkhvKRYZ1uH8WeIsrRSDrU+Sgm65nl+ZPadgejvot5al3+AJuUAVj53gffbubO03sdlEtfdLvDuWZTr3EXj/e8ZCanl9klIZYcN4FGmfFnavzTtZ6uEFHA8L+HXH20CSBJSBGdgTMphCY6UA6Bl1HBOlg/yxp8hyqpSDh+l9lFKz6vC8yMz/d9Efxf1hinlAFa5eotHrqdO1Hofl0lcd7vkpkzgkZRrt433P9slpDL93uCLWsldjbSTI5CfsVFCquN+ju9qjH4XbQIIskUkIUVwAt1dygGQmzIe7UMSZWmlHGp9lG3DtB8SXZabPhlNygGs436L+JDovI/LJK67XeDds4Wb91E33f9qJaRAVsT0/aNMxcIt9QTQUgkp4HjWZt7iAWsCKCSkvG+fzvu4zB0ES9DdpRwA+Tkz0baSoiytlEOtj9KCrsFWUmsF/X3UGqaUA1h1K+ltrfdxmcR1twts42GlbtRKSEFfNH3/KINtX9Y3vbGbxr807WerhFRt6gbWBJAkpAjOwJiUw8e7jZNBQACtSxejJZNHWSDlUJaUcqj1UVrQNWUyuS7DlnIQyeT9emq9j8skrrtdIJEf6/CWzRJS4vCWN3bT+Jem/UB+xkYJKeD44PAW1gSQJKQIzqC7SzkAqs9wxPgzRFlaKYdaH6UFXf1ngJw37PdRaxlkKYfaZ+isfKvtHi6TuM52gXfOolxeG2D0v2ckpJCeIcyAL9LKN6XlDVslpOA7w7amPc7HmgAKCSnvGXTex2XuIFiC7i7lAChs3YIWhYwyFdG31IKuCqKQqs0GKQewIArZkStpu4fLJK6zXTpyRdTom80SUiL65o3dtP7Jtp+tElK10Tcs7iAJKYIz6O5SDoBqHuJm488QZSry71ILun7wfuo8RNVmg5QDWJCHWLnzUNs9XCZxne1Suf0QNf/OZgkpFfl3aceVyEO0TEIKcs3ZYt/jfCzuIAkpgjPQL+WAdwI3IIBScBJ59SrjzxBlKk7gphZ0DU4iH5Q/iazaak/gYk4Ag5PI5cs3tN3DZRLX2S7ly9dRT+B2kZBCOIkcZqAakPYEbtpxZauEVO0JXCzuEBJSUyZovY/L3EGwBLoHCLaUA6CMqEUYZqoINLWg67ZtqbUIVVstgWJOAAMtwtKZc9ru4TKJ62yX0ulzqBp8NktICQ2+bfIafCrGlY0SUkKDz+N8LO4gCSmCM9A9QLClHAAVUY1khvFnCCUJRVsoqfW8PtmbuhqJarNBygEsqEZSPPa5tnu4TOI626X42XHUKhw2S0hVq3DsS+1fmvazUUIKKk6x9vI4H4s7SEKK4Ax0DxDMJOqAADpu+vWIJ40z/gxhpkLKodZHaT0vUY94Bfo7Caw2iRpzAhjUI27ff0DbPVwmcZ3t0r7vAO+XSHV4bZaQgtrhbGGSog6vinFlo4QU1Jxnz3TzHt4EsOYQm877uMwdBEugc4B0lvGlHACdmVY+2XpvGMpzNDIVUg61PkrreZ08wydbixagv5PAamUUMCeAhR07eHR0505t93CZxHW2i4l336xdAJgyVmHWumg+n5Se+iq1f2naz0YJqZaRw3hU8mErKneQhBTBCegcILZIOTwqPuIT0cH9UJ6jkakSUk2t53XBr3c6cyr6OwnMBikH9hz79muPQrlM4jrbRURf9x1A6YM2S0jlZ0zl25wXr6b2L0372SghlR3Ul0+8it+QhBSB0Aw6B4gtUg6PHv3maeatHk8zvV9DeY5GpqqUUmo9r1v3eSRywhj0dxKYKKWEKOXA2ijIQ1uhLw/NZRLX2S6Q+6c7/7JZuwAwS1mGWW7CaB55u/UgtX9p2s82CanOTo/ne73mWQ/2a5KQIhCaQOcAKV+6ZoWUA/w/O7A3XxmWHqM8S72pkHKo91Hm33dkC3ySPmII+jsJzAYpBzATJ1FdJnGd7WLiBHazdgEICSmvT2I8RyODscqiS9n21P6laT/bJKQg6sd2egb2UeajrFUlpK5ru4fL3EGwBDoHiC1SDvD/KmkWUJ6l3oSUw3Z5KYd6H2X+PUyIOWn2Rn8ngdkg5QBmYgHjMonrbBcTH9Bm7QKwUUIqOyBYzD5J7V+a9gMZGpskpDoy/mJ25FBlPsoaSUgRnIDOAWKLlAP8H7Y4+bbJfZRnqTcVUg71PspeA7bGYYsctk2w3wtYfha+lANYkMKQGz9K2z1cJnGd7WJiC61ZuwCqElLTUZ6j3tg251uvemP2dSX+pWk/2ySk4OQvG68TxyjzUdZIQorgBHQOEBNJ9M0GSOAfHHJgk4oL8onTKk2FlEO9j7LXgMMxLKLQ/gj9vYABgWNLOYCZOMTkMonrbBcTSfTN2gUgJKQmjkV5jnrrLPgH2oakO9CmYlzZJiFVvnDFP9A2TZmPsmbiEJPL3EGwBDoHiC1SDvB/kDlJK52g0qpSDmeV+Sh7DZDHCaQTsN8Le55AyiHThkriJmSMXCZxne1iQkajWbsAbJOQ6niQ95/nHSX+pWk/4FKbJKSEpNXiBcp8lDWSkCIow0svvTT65Zdf/ifPpnu//tu0P1cLnQPEhJBuswES+AerVBZxO5ou4qbKVEg51Psoew0QyGYRtxt30d8LWHZQHyukHMB0C5nrJHGdvAHQ1S6mhHSbtQtASEgN6ov2LLVWua5G1F7FuLJNQqp49LNnDuzgSkjpFzKnCeCPAB4h//0rr7yyFn7t/f9vPJLek+bn6qFzgJjIg2g2QAL/IE+FTUY/2YvyLPWmQsqh3kfZa0CJvCDnDvu9cCmHHlZIOYDpLmWoi8R18wZA2wTQUCmtZu3CJoCBhFSv16zIkS2fv8QnXXPSlbVUMa5sk5ASOYmbNirzUdZM5L/TBPBHAI+Ux3kk3Sf4vUfQ7Wl+rh46B4gtUg7wfzipxsghRQF1laZCyqHeR9lrwAlH1k5fnEZ/L0LKYRC+lANrp1HDeTvdz2m5vi4S180bAF3t0nG/hW9zjn4XrR8+KyHVxxoJqdIXp/xTyYuU+SfdTpZJSBW2beOL/I8+VuajdDuRhBRBBTxCXurZqzW/Lzz33HN/Jftz9YAB8vgx70yqLe9LOVSu3NBy/WYGfgX+gVYVmwCuW4vyLPUWSDk8Kj9R5qPsNdpWr+ITQF93D9M6s21CykGVf2ksN2U878PXb2u5Pvilji2S84EsbwB0tQu8axZZmjIBrR/W9rtgsdbpTXiwniew4pGjfGtxzSpl/sle41G5KiGF/V7ACoEu4aHDynyUtcrl63wCOGOKtnvo4g6CRfBW6Mu9Ffovan5ffv755/9S9ufq8VQjCpP4NucfKyWdt4mFf7lwnkdy1q7AfpSnP/zwA5NyyPZ5HftRGB7v3snezXefHsZ+lKf/1s6jCoWp47EfhaG0eB57nt/fva3tHurYIjkfyPIGQNf7+P2dWzwlYck8XbdIhMJUniP7b8UC9qN4Y5QvZB/v2YX9KAzZ3q+zdA3gNGx0rOHKCv9y8Tz2ozz9Y7nEeWzSGK33UcMWBGvhb9H0qvl9Kc3P1QM6ka4VUosv5dCZL6GsCGtXgOWzvPZu6/zZKM9Sa4/aq1IOKn2UvQbUOWVktXUL+rupXPSlHGZNV+ZfGmtdutjfHj+p5fq6VvG6eQOgq11KJ77kY3XpErR+WNvv8rOm8SjwxatozxNYYYtfm3j3bmX+pblOICEFh2Ww342oTXzuglIfZawzkJB6d7C2e1AE8EcAj5D/Dlbp8OsXXnjhZQ8H4Nceab8Y5+eaAQYIdCYdOQq2SDnA/ytXeVQhN3UiyrPUmioph3ofZa9RPHSEbyutXYP+bmyScgCDdxJsK+m4PvilmjOi+EAVbwB0tUvx4GH0/ljb74SElNc3sZ5H9Mc1q3l/PHxUmX9prmOThBRwO5uoe1yv0kcZIwkpgjJ4pD3LI+lfejbnxRdffMn7o594RJ31/vyvm/xcU+gaIDZJObAJ4N0sn3SNGYH2PIGpknKo91H2GqUTJ/mk6/3F6O+mWFd7FXsCWNi6lUdcPt6t5fo6SVwnbwB0tQsk8fOI9Fa0fljb76oSUp+hPU9gMEZ5RPqUMv/SXMcmCSk4NMQmo/dalPooay5LSBF+JNA2AbRIygH+39Fa4c8zbADa8wSmSsqh3kfp5zl30X+emejvpn3PJ76UwyZl/il5ns2btFzfZRLX1S7Q9mzS7b17rH5Y2+9AVsQWCSngDLbN6XGIKv9SPY9FElLwrWE7Th7Xq/RR/nnclJAi/Iiga4DYJuXAIpLe82T6vYH2PIGpknKo91H2GpVrwanL8ejvRkTcLJByAKuPSKo2l0lcV7vAu2YRN+/dY/XD2n5XlZDahvY8geUmB6fS7yjzL811bJKQyvTr+UzEDZs7RETSMQkpwo8IugaIyLmbMgGNEOoJINP/TT8n8Tu0ZwKD/J1AykG1jzImchJHDUd9L2Ai5+7gYWX+pbHSl6f9yfpCLdd3mcR1tUvr4oXoOXe1/S6QkGr7cC3a8wTWMuodPqnwxqwq/9JcJ5CQwpysg0GeOVvgexyv2kdZExJS3gJbx/Vd5g6CJdA1QOAkFttWnDsLjRTqCSD7zkBOnnmcAvOBte/ewyMKW7Yo91HGxHb9kP6o7wUMTn6yj//nXyrzL43B1hbrx7Ona7m+yySuq13gBDj2tmJtv4O+GJxKxnqewEA5gC1iC53K/EtzncLmzejb9WAdOS67Ahyv2kdZg28fP5V8Ucv1XeYOgiXQNUBsIM16AmgZO5KvyO5m0Z4JTEg5KDhYoGQCGBzY6fMr1PcCJkjz7AVl/qUxSG5nkeyJY7Vc32US19UuuYlj+Di9eQ+tH9b2u/JXXEIKZEawnicwdrDgrVdTl6VTNa6EhJSCxWwaq9zJ8F2Mce8p91HWxGL2xEkt13eZOwiWQNcAsU3KAX6fmzaJTy6u3EB7JjBVUg6NfJS17IBePLJQxpHsCQxSBmyRcgADeQsu2TNMy/VdJnFd7dIy0pcWybSh9UMbJaQ6y094lGtAb6X+pbmOLRJS5cs3eBt5HK/aR1lzVUKK8COCrgFim5QD/D4/fw5fkZ05j/ZMYKqkHBr5KGstwwfzj25LEfXdVBOn7ZBy6AxEuwf11XJ9l0lcV7tAHWi2GCl+g9YPn1EQuId/oA0M6oYH4sIq/UtzHVskpKDePIvSzp+r3EdZc1lCivAjga4BIqQcEKUT6gmgddlSviI7fgLtmcBUSTk08lHWcuNH8cjb7Yeo78Y2KQfYasu81eNpptdrqbfdwtoPmwNkoaNd2Pvu1YOZjvedpF3EBNASCanK7Qc8yuWNVZX+pbmOLRJSxWMn+ER0+QfKfZQ1kpAiWA9dA8Q2KQf2TOs+5JPS/QfRnglMlZRDIx9lDYqWs0nppWuo7waEw22ScgDLDvQjUqXHyq/tMolrmQAWv/Ejrn1Q+2FjCSk8UXuw8sVrfLI1Y6pS/9JcxxYJqfb9B/hW9Lp1yn2UNZKQIlgPXQPENikH+H1h+3a+Itu5C+2ZwFRJOTTyUdbyC+fx9jp9Fu29CCmHmvJJ2CTO2mvEED8nraD82i6TuI52gbw/ts05cihaezfqd1UJKbwc2dKpszzK5Y1V1f5Jt5clElKFnTs5t+/YodxH6fYiCSmC7dA1QISUw4UraKRQTwDte/dzkti4Ae2ZwFRJOTTyUdZaVyzjEdvPjqO9FxulHMByE/SdSnWZxHW0C7xjfup6DFp7N+p3NkhIwdhkEaUVy5X7J2u2SEi1bVjPd3f27Vfuo6yRhBTBeugaILZJOcDvi58eU0agaUyVlEMjH2WtEYGatsqdh9ZJOYDlZ07zFzNXlV/bZRLX0S6wYGQfzVl6PppJ2qXWPyEhdSeD9kwqF7DKJoCWSEg1WsBic0d1MUMSUgRLoWuA2CblAL9XuYUiayqlHBr5KGuNtlBMW/nydU6Y0ycr9y+NtS5eoC2dwWUS19Eu8I7ZGF2sZ9ssSbvU+ickpC7jSUjB2FSVwqJyXNkgIdUohQWbO0hCimA9dA0Q26Qc4Pcqk6ilSUGhlEMjH2VNJFGvX6fkuWTMRikHsLaVK3h04ehnyq/tMonraBfdifNJ2qXWPxskpOCAg6pDbCrHlQ0SUo0OsWFzR/VAE0lIESyFlpN8QspBj3RGkgFS61/lljoZBVlTKeXQyEdZaySjYNqKxz63TsoBrLBpozZJI5dJXEe7wDtmUa5NeqQzkrRLrX9CQuoYnoSUShkrlePKBgmp6jM80OKjjOn+DrrMHQRLoGUCaKGUA/xedfRNxlRHIVWRnIi+LZir5LlkrH1f1ygkNomz5wpEzbdtU35tl0lcR7sI8VzvnWO1d6N+V42+HUB7JoiMq4pCqhxXNkhINYpC2sAdJCFFsBo6BkhVykFP7kOSAVLrX2dJbf6djKnOQ1RFcqKUUk3+nWmzUcoBrHjwEJ+YfrhW+bVdJnEd7SLKZx3UUz4rSbvU+meDhJTKUpZKJ4AWSEhV8xCfaPFR1kDOiCSkCNZCxwDRffopyQCp9y/T+3VlJ3BlTPVJZFUk16iYumlrW2+flANY6fMv+aR96RLl13aZxHW0C7xjNpnw3jlWezfqd8EJXDgtj/VM4iTy3axy/1K1GbKEVNhJZBu4Q6cahsvcQbAEOgaIrVIOYCo1+GRMtRahKpITGnzDB6G1V+ty+6QcwMpnL/D+PG+28mu7TOI62iU/dxaPcp27gNbejfpdoMEHkx2sZ1KpRahyXGFLSIVpEdrAHSQhRbAaOgaIrVIOYCqrcMiY6q0kZXpeDapwmDYbpRzAKldv8Yj21InKr+0yietol9yUCTxi4r1zrPZu1O9skJCqViP5Trl/aQxbQiqsGokN3EESUgSroWOA2CrlAJabNI5/YBTU4ZUx1fWIVZIc1DqtrcNr2nLT7ZNyAOu418I/MKPfVX5tl0lcR7vAO2YLtPstaO3dqN9VD29NQXmeaj3iN7T4l8Ya1eE1aaIe8eRn6xHbwB3wDSQJKYK10DFAbJVyAMvPmcEnGecvoTyTSimHMB9lLTv0bR5haOtAeTeQf1gvJ2EDiXe2VvgW07AByq/tMonraBfsPhjW71TLN2H3QZXjCltCqnzuIp+cz5mpzUdZIwkpgtXQMUBslXIAa31/MQ/Jf3EK5ZlUC8qqJDns6IutUg7V6EtP5dd2mcR1tEumL24UOqzfYUtIiSj0mBFa/EtjjQTcTVrpxEk+AfW4XZePskYSUgSroWOACCmHQ3ZJObBnW7OKP9vhoyjPpFLKIcxH6WebOhE1/yr79ltdSkrZQOJg1fwrteWuXCZx1e1iQx5qWL+rlnDshfI8qvNQVY4rISHlcRvGuykeOsK3oNes1uaj9LMdPEwSUgR7oWOA2CrlAFbYsoVHJz/ejfJMKqUcwnyUNcwTmDZLOYCpPIFZ7x82B8hCdbvYcBI9qt9B38SKTqo+ia5yXGFLSAGXsyibx+26fJQ1kpAiWA0dA8RWKQdGFrv3NCQLU6Z6IqFUzwtx4m6zlAOYmLh7HzuV13WZxFW3S+XOQ3Qtyqh+hykhJSYSH7yvzT8aky5JAAAgAElEQVRZExN3j9sw2qqweTNf1O/5RJuPskYSUgSroWOACCmHa7fRBl4YAcDWL98uWIXyTCqlHMJ8lDXYpsCqwtBxP2etlAOY2Lq/rGbrvtY/bA6Qhep2KV++jl6NJqrfYUpIqa5Go3Jcia17j9sw2qptdeO0Hhu4gySkCFZDxwDBPkwQRQBw+IOtpJcsMv48qqUcwnyUNczDO0LKYYp9Ug5gKuuw1vuHzQGyUN0uNtSjjup3IDOCtbBVfZhA9bjClJBqXbLQP9h3WquPMkYSUgSroWOA2CrlAAbyL1wyYIZ5MtAgJ6JUzwtRvsdmKQcwId9zTI18T61/2BwgC9XtUjz2OaqcSLN+hykhpVpORPW4EpzvcZzpd5Of7bfL15e1+ihjJCFFsBo6BoitUg5gIADNIk2Txhl/Hjj4oVLKIcxHWQOxUiwBb5ulHMBA5JYLeB9Qel2XSVx1u7Tv8wWF1+MICjfrd0JCyuurxvvfyhW+oPAxbf6lMbHrc8/8rk9V3P+uVh9lTBxuIwkpgo1QPUCCfJCshVIOYKJs0HvvGH8eHfkgSvW8EEv4gWQQ+/ivXaPNvzQGZa5UlvCr9Q+bA2Shul2wS4o163cgM8LlrY4Yfx7VJcVUjytMCamW94bxyefDVq0+ylomkLciCSmCbVA9QGyXcugsPPJPm/Yz/jzlr75WfiJMqZ7XhSv8+WZNN/5uhJTD1q3a/Ev1fHv38wnqhvVKr+syiatul7b163mUdd9+1LYO63eYElL5mdP4NueFq9r8S/V8gfLDWfPKD9nB/uns9kdafZR+PpKQItgK1QPEdimHzs7fPM289erTTO/XjT9P6fgXSqUcwnyUbrub93iEcuIY4++msHmTtVIOYMXPjvO2W7FM6XVdJnHV7dK6fBmPsHnvGrOtw/qdkJDavNn48+QmjOERtlv3tfmXqu0QJaQyvV9jnA7crtNHWRMlLklCimAbVA+QqpQDTtH0OASQHdCbrxhLT4w+j2ophygfZawj08Yn7yOHGW8rUTT9yKfa/EtjpdNn+QRw4Tyl13WZxFW3S957t2wScfocaluH9TshIbXavIRUy8ihPIqUKWjzL42J6k+GJaQ6S4/5js7A3tp9lDWQNSIJKYKVUD1AbJdyAGsZMYSTabbd6PO07/pIeV1IpXpexW84mQ7qY7ythJTDl/ZJOYCVL17j/XqG2oWNyySuul1g0cg+lJeuobZ1WL8DmREsCanswD7+ovWxNv/SGJaEVEe2wBetHqfr9lHWSEKKYC1UD5CqlIParTLZAdLIv9z4Uf52ygOjz1PYqFbKIcpHGWPb471e86xHl+0U3ZafPd1aKQewyu0HPLLt9R2V13WZxFW3i9gqu/0Qta3D+p2QkJptVkKKp630YFudOv1LY1UJqY1G3w1sibNxOWG0dh9lDWSNSEKKYCVUD5CqlIPaZHnZAdLIv/yMqXyycVFNQnVcq0o5fKbdR1mD6B+LNBS/MfpuchPH8o//DfukHMA6Woo80jB8sNLrukziqtsFDo6xyHyuiNrWYf0OZEYwJKSqkfm+Wv1LY5C6gSEhBYdi2KR85lTtPsoayBqRhBTBSqgeILZLOYC1LprPQ/KnvjL6PK2L1Eo5RPkoa5D/x3ON2oy+G3FfS6UcOstP+Ed4QC+l13WZxJVPAAO5jLJauQzZdqn3D/oml5AymyOr476qx1VVQmqB0Xcj7ruo631t4Q6SkCJYC9UDpCrlcAB10EURQNuK5TwS96kaUdW4BqtUlVIOUT7KmojE3bxn9N1AdMNmKQewTJ9fKRc4d5nEVbaLEMz13jF2O4f1OyEhNdishBRExVVHHlWPKyEhNXOa0XcDwtgs8rhyuXYfZQ1kjUhCimAlVA8QIeVw7HPUQRdFAIWNG/gkde8+o88jpBwUTq6U63nN8nPxPEI39V5E7uFbXXMPbSFxsOyQ/spLHLpM4kongN47ZZOrof3R2zms31UlpNTl4sUxyIvluYfq9DlVjyssCSmRe7ixa+6hLdxBElIEa6F6gNgu5cBIY9cu/zTudqPPI04fK5JyiPJR1qAKiOpt6mYmcpwGdj19bAuJs/Yb9Q5vvwd5pe2HzQGyUNkuHfdzfJtz1HD0do7qdyA3ovI0bhyDk/H89LG6Cj2qx1VVQmqo0XYCRQW2mN/1kXYfpduPJKQItkL1ABFSDpevow66KAJo33+Qh+TXfWj0eXR8PJTreYXo8ek0mBDbLuUAlps8nkdwr91W2n7YHCALpREk752yCNKU8ejtHNXvqhJS6hZxzUwcsFCoP6h6XEUt4nQaaKoyvjpwSLuPsgayRiQhRbASqgdIVfXcTikHsOLxE3xFtmypsWcRUg69XlMqsaJcz2vTJuVSNc1MbB9N6Lp9ZAuJg+XnzOSLm3MXlbYfNgfIQmkO2bkL/CM5dxZ6O0f1O5AbUVmRI45BdRxegWSTdv9kjadx9DAuIQVVldiOxfEvtPsoayBrRBJSBCuh/CSf5VIOYCUNNXmbGRxuUC3lEOWjrIGQK/vY1NXk1WlRCeS2kDhY6/uLlZe7cpnElZ4i9d4pW5R57xi7naP6nY6DXM1MiCwrrEGsY1xhSEgBh7P28DjdhI8yBt9Cxv3et1HldV3mDoIlUD1AMv3f5CRQ+Q510EURQPnKDb4imzbJHAlokpBQrud16DDfblq7xti7cUHKAUxHuSuXSVxpv9NQJjFtuzTyD0NCSvS7Q0e0+5fGwqScdFpu6kQ+Abxy04iPMtZZ+ZY9Y+btt5Re12XuIFgCpdsA3qSPdXRvEog54JoRQOVulk/Gxoww9ixCymHiWCM+ypqIxCxdYuzdgDA2l3JYod2/NBaVcJ6m/bA5QBZKI89IB7Oi2qWRfyA3wsXczUlIwVhkk84TJ7X7l8bgBLBpCSngcHZPj9NN+ChrmX5v8MAISUgRbILSk2D5Eg91vzMQfcBFEUBHvsyfc9gAY8+iQ8ohykfp50TIxYoqI2UTiYNsEJec2KC0/bA5QBZKDx9t8PVD9+5Hb+eofqejnGMzg7GoI/dU9bgSElJ15Rx1GnA4izq2Voz4KP2c3jeRPaf37VHZhtgcQHAcSk/y3dGT7JpmgDTyDyNSWS0kr07KIcpH6TYUpzEnGHs3Lkg5gOnQ83KZxFW2i036oVH9DiNSCSejdZw+Vz2uhITUl6eNvZuoyJpN3FE9HJlR2obYHEBwHEqjR+K4e9e6jBgWRQA6QvJRpqtWpnI9r/stfHt89LvG2klIORy0V8oBrHTmHO/fC+YqbT9sDpCFynbJz5/LJw9nzqO3c1S/A7kR07mKMBZZ9Oh+Trt/acy0hFSzhbxN3AESMKrl0VzmDoIlUJo/dupsaDI/hkURgNg6UBiSj7L23Xt8KYfNxnyUMYyKDCLHqcHpWptIXMfhIZdJXGW7wDsNS+bHsFAFgeNfcI774H1jzyIq0BQ6tfuXxkCmhkXy93xi5L00SzmyiTvE4aHTZ5W2ITYHEByH0pN8QV1GxVGuNAMkzL+o5GEdposcteh5sXJXrxtrJxekHMB0HB5ymcRVtkswHjvutaC3c1S/My0hxcZj78ZlEnX4l8Z0LXLDrNl4tIk74IAbi44qrD/vMncQLIHSk3xBMr9CwdK0AyTMvyj5AC0EoGl7RIue18A+RstdBW1RuXrLiH+y1tlaUX54yGUSV9ku2aFv8z6nsM5y2nZp5B/wBYsCe33WSJ8LKmwMUlthQ8e40pXmEmbNIvI2cYcOgX2XuYNgCVQOkMKWLcoFS9MOkDD/gqhTqUHUSYfBtrgO/TAtel7v+XpemTYj70bkODWI/thE4pAvmnnzl08zfXsqbT9sDpCFynbJ9PkVe7emcnLjtEsj/0xLSFX1Q98x4l8aE3qei82kAEG+KIvGzp9jzEdZg2+iaoF9l7mDYAlUDpC2Nat4lOvwUfQB14wAokoI6TCRBHzxmjEfZS03aRyPyF2/a+TduCLlwJ51QC8eqSo/UdZ+2BwgC1Xt0ll6wqNcA3qjt2+zfmdaQqpy/Q6Pck1WWyNZx7gqX7xq9BBgs5KeNnEHfBNZdHTNaqVtiM0BBMehcoCAxIlpGYBmAyTMv7Z1H/Jo5f6DRp5FyADcVlsjWYueV1Dz9vwlI+8GImph0R+bSJy144ghfLKabVfWftgcIAtV7dKRLfAol/dusdu3Wb9jUWA4edpPXRQ4ykD7T4cup45xVbn9wKgMWPv+A3xS5XG5KR9lrSoDtkhpG2JzAMFxqBwgQgj0whX0AdeMAAo7dvCQ/M6dRp6lKgRaMuajrEWdylVtEEljEZWQMkk2kThYboLaagcuk7iqdoF3yavkjEFv3zj9Dkp68Sjwt9qfQ1TmUXzqWMe46siZLQQgONz7vykfZU1HIQCXuYNgCVQOEPFxvHUffcA1I4Dq6nGdkWcRuoOKayRr0fOK0OVTbc2iPzaROJjqagcuk7iqdtFVJSdtu4T51/LuYKVR4CgTuoMhUS4d/smaaYH9Zrs4NnGHjkWOy9xBsAQqB4jq7TEVAyTMP5E/YkDPSxQD10CMWvS8tm/3K3Ps0v5uBDFOaEyMNpE4mEhz+EJNmoPLJK6qXUpfnFK+PaaiXcL8y00YrTQKHGWFnbsio1w6/EtjwHF8oas/Oip2KkLyuG3iDh1pDi5zB8ESqBwg1QR5/YM/7gAJ86981lzN246WIh/8wwcb9VHW2vf50dH167W/m2bRH5tIHAySuFUedHKZxFW1S/HQEd7f1q5Bb984/c5kzdu29ev8KNcBY/6lsezwQTwIkCtqfzfVGskXjPooYyLVReFBJ5e5g2AJlJ3kCyQyDCVHxx0gYf6JmreKT9c1ssotfcnRWvS8jvnR0eUfaH83pRMn+b3eX2zMvzQGMg4qpY5cJnFV7dL+0cfKJTJUtEuYfxCp5FHgU9qfA064sgXH8RPG/EtjwHH8sNsD7e+mqlZwx6iPshZ12E22DbE5gOA4lE0ANYjkqhggYf5V9bWGaX8OOBTDolwzpxn1Ufp5DVY7KB48HBn9sY3Ehdj5JjVi5y6TuKp2KWzaqFwkV0W7hPkHfZVNyg4d1v4cokrO2cZRLh3+pXremVP9g4BXtb+blpG+XqnH5SZ9lLVA7kqV2LnL3EGwBMpO8gUCqWNHog+0OAQgFPYHqlXYb2Qgi8MFUhca9VG6La/eMlbtoH3XR3xCtW2bMf/SmCh3uHKFsvbD5gBZqGqXtpXLlZfJUtEuYf6JKPBHH2t/jtyUCTzKde22Mf/SGIhAs+joyTPa3012YG8+ofK43KSPsqa63KHL3EGwBMpO8l32y/JMn4w+0OIQQLXG5qtKa2w2MiECunqVUR9lreN+jk/mR7+rvY3aNqznH9O9+435l8ZKp87yyfyi+craD5sDZKGqXVoXzuOThtNn0ds3Tr9r37uPL1o2btD+HC2jhvNJw4O8Mf/SmK6Sl/UmUo4iapbbxh1Qso5FR6/cUNaG2BxAcBzKTvKdPse3DT0yxx5ocQkgO6S/0pB8mIkyQFu2GPdRxjoLj3h0dEg/7W0EeYbsg3Hsc2P+pbHypWt+tYMpytoPmwNkoapdctP9KjmXr6O3b5x+V/zsuJ8ju0z7c2QH9+Mc1f7ImH9pzFQ5UOBsxlFD+xv3UdbyC+byhc6Zc8raEJsDCI5D2Uk+nxTbVixHH2hxCSCqBq1KE4XA93xi3EcZY9HRt3qwCKnu6CjU8eSkeN6Yf2mscuchj46Oe09Z+2FzgCxUtYuoknMng96+cfodfMDZImD+XK3PwMZhr9c866F8HOoaV8BxbLG7WU2ObJiJlKOIXQrbuKN1xTK+2PW+laraEJsDCI5D2Uk+sS2yEX2gxSUAyHHjIfmbWp8D8sXYwD+qPsdJm5zDoL6R+TWqLGgDyDs06Z+sQSUXldUOXCZxVe1SrZJTRm/fOP0O+MJEjqzIUx6sPhKva1wVj37GAwGrVmp9N7CNytpg2iTjPsoapAxEpbvItCE2BxAch7KTfNu2GUuMTjJAovyDFbzKkHyYiRynU+pznHSRXMt770SesFN2nyDH6X7OqH+yprragcskrqpdRJUcRfIYqtolzL+O+y1GcmQh74/dZ9Q7Rv1LY6VTXynNkQ29T5BytCA8Cmsbd1QPvG1X1obYHEBwHMpO8hmURkgyQKL8gxwelSH5MBM5TpeuGfdR+pknj4/U2FJlkGfIPv6FTqP+pTGV1Q5cJnEV7SKq5ITUgsayyANkQf7ZkPD8MxUmtEqnqNcq1TWuyhfV5siGGZwYZxPNFeF5mLZxh5C8+nCtsjbE5gCC41B2ku/9xTzKdeIk+kCLSwDVkPw+rc8B0ji6cpy06Xk1UdlXYSLH6a3wHCfbSBxMZbUDl0lcRbvorJKTtl1CJ4CGcmRFtSINepy6xpXqHNkwE3qcESlHtnGHEL1fukRZG2JzAMFxqBog+TkzjJVHSjJAovwzVYEgEADVkeOkTc/rg/f5hP7zL7W9FzjZyCIpg/oa9y+Nqax24DKJq2gXUSVnwmj0dk3S77KD+mjPkYUat2zCsGypcf9kTXWObJjF0WK0jTvK5y/xCf2cmcraEJsDCI5D1QARZXkMFEhPMkCi/IPtahaSX7Na63NAeTyVJYCS+Chrbes+5NvjBw5pey8ix+m98Bwn20gcTFQ7uJi+2oHLJK6iXaBihK4qOWnbJco/qCCkQ5+v1tr3H+T8tG6dcf9kTeTI9ntDa/u0rVnlpxwdMe6jrFVu3OWLHe9bqaoNsTmA4DhUDRBRlidTQB9ocQkAanmyFfYS9RU6Auss8xynrKYcJ216Xjt28Ojozp3a3k2cHCfbSBxMZbUDl0lcRbvAO9RVJSdtu0T5J3JkFVfoqDWdY1DnuIJ8ThYdLafPkQ0z6C9sDH5xGsVHGevItPkLXjXlR13mDoIlUDVAoKQaG/Slx+gDLS4BwHY1iz7Mmq5v0Gfb+aB/V0+OkzY9r/0HePRhvfrog3j/MWoO20biYCqrHbhM4iraBd6hrio5adslyj+RI6u4Ru8z/WzdOr7Nuf+gcf/SGORzsmBAS/oc2TCDiDF7/xeuoPgoY/Bt5CkvasqPuswdBEug5CQfS4p+9Wmmz6/QB1kSAqjcuq89/wi2xPk9xqD4KGs6848CKx470fQetpE4WGHzZmXC3i6TuIp2ad+9R1uVnLTtEuUf9Fm2CDh+Qtsz6MzD1TmugE9ZdNTjV13vRuTh3grPw7WRO6B0XdSht6RtiM0BBMehZAIYoywPhjUjABGd03gCUXeUUZucg8YTiIG172seZbSRxFVOWlwmcRXtonIyrdKa9btqdO6AtmfQeRJf57iKE51La+IkfkSU0UbuEOVHQ2SvkrYhNgcQHIeKAWJKGFVmgET5F+Tn6dQggxwVnXmG2uQcRH7eBG3vprB9u5/jtMu4f2lM5balyySuol1UbqertKYSUjt38r67Y4e2Z4DcWF15hjrHlcjP+zI8Py+txdHitJE7RPnREOH7pG2IzQEEx6FigEAZLxOlkWQGSDP/RBWCyndangFOqek8aaxNzkFjFYLAQBCVffwPhp80tpHEVR5ccJnEVbSLygM1Kq2pgsCBQ0pFfRuZzmo8OseVOKF7+KiW9xK3Go+N3NGs9GXSNsTmAILjUHKSL0jmnz8HfYAlJQBRhzRX0vIMurUGtck5BBp9GuqQBgaCqM1ynGwkcZXSJS6TuIp2USmpo9KaKgh4fValqG8j01mPW+e4gtQItj3+8W4t7wUE2ONoDdrIHZBSw/q7981U0YbYHEBwHEpO8gXJ/Ms/QB9gSQkAFOu5qO9DLc9Q2LSRk+Ene9F8lDFepaMHq9Shq9qBEA8/f8m4f2lMpXixyySuol1UimqrtKYKAucuKhX1rTfd40/nuIJ8Trbo3bRJy7uBvsLGn9d3sHyUNZWHh1zmDoIlUHKSTyTzr0cfYEkJID9DbwSibcVyPuA/PYbmo6xB9I9FINofaXn23MSx/ON/4y6Kf7ImypcpkPZxmcRVtIuQDFFQVk+lNVUQuK5W1LfeOgt+BH6Ingi8znFVPMrr9LatXK7l2asR+KloPsoaHHhTdXjIZe4gxMRLL700+uWXX/4nz6Z7v/7bqJ995ZVX/qv3v//43HPP/dWLL774UpzrKznJ5wuWtu8KT+bHsDgE0LpIbw5SfuE8fv3TZ9F8lDXI/9NZ7aBl5FBfPLwNxT9Zg8RzVeLeOkncBe4QosGacnDTtEuUf5CXxxYBI9WI+na5vsjBHY7iXxornTrLd4Q87tPx7HC4hOfgLkDzUdbgwJuqw0M0Aezm8Ej77z1iXgu/9v7/Nx6R74n6ee/vr3k/99izvc8///xP49xDyUm+oGxYRDI/hsUhAHEKUVPCcm7aJB5hvHwDzUfpZ58yQWu1g+yA3r54+BMU/9IYOzykoLyfLhJ3gTviJvNjWFMFgUDUd2BvLffXfbBO57gqX77On336ZC3PDlwd5xS+jdwhDg8pKO9HE8BuDo+Mx3lE3if4vUfS7U1+vmfSeyg5yadRsDTtAGnmn+6E5ZYxI/gk6m4WzUdZEwnLGqodwMQJJlDNxMNtJHEwcXgoX07dfjLc0AwucEdHvhQrmR/DYikIeH1XV43vOFVydPsna5U7GR69HDtSy7MDV8fR4bSRO8ThIQUC+zQB7ObwSHupZ6/W/L4AWzRhP++R+JwXX3zxf3r/H/uzn/3sv8S5BwyQx495Z5I1IVh6/mKq66g28KuZf8VP/ITlzZu0PEN22AAe5WqroPkoa21+wnLp8y+UXxveB/v4e+8Hy780lvMPD3XczaRuPxVcUQ8XuKPj7kMeKfLeJXZ7yvS77NC3fVHfDuX3Lx3nB+vali9F80/WOlvLsca2rAUH64qf7EXzUdZA1JtP7GcpaUMVXEGwFB4ZL/dW8b+o+X35+eef/8uIf/IT+M9Pf/rT/+QR/vk493iqAO0z+Dbnv7W1qricUfzmq1OcxDes1XL9bN+eLErww5//rOX6OvHNDh4d/fWJY8qv/ccOPgFsmzBK+bVNoDh3Onv+P2Qfpr5WSppoCBe44w8ZPgEszpuR+h1ioG0CXwT8qbOi/Nq/PvEZu/Y3O7cqv7ZuANcB52X79dRy/c4Na9i7+e3Z01qurxP/1spzO9tnTlJyvZQ0QcCGR8z/JxCuZ+fqbA+sxj0S71Xzs6Ww63ir93/0/n6h/9v/4P3738e5P3SitCukQLC0M9OKvsJKugIsn64mLKu+/6PyE74SHtAL1UdZa/erHbTv3KH82hU/Tyg/fTKaf2ms1T/cA/0nbfv9WLlDjL1F89HbU6bf5f383sqVG8rv315zsA7LvzSW9Q/3PKo8UX7tuGPPRu7ofFgV2FfRhrLcQXAAHin/Hazk4dcvvPCCx8svHwj+ziP3F2t/1iPx/+79zH+DX//85z//z97PHotzDxgg0JnS5CLoFCxNmyPRzD+dCcsdmQIf7COGoPooa+37D/oJyx8qv3bpdLyTgjr9S2MgcaFC3gf8UskZAVzgjqpcyAr09pTpd9UT/ufU96+gSs4BPQfrdI8rkEhiKRLZgvJrxz1YZyN3qBTY18UdBIvgkfUsj8h/6efoBPIMP/FIOuv93V/X/WwfWPV7fzfN2Ek+A4LBaQZIM/9EwvKYEcrvX7l5j08uJ45B9VHWRMLyB+8rv3ZcrTAbSRxMlcC3ThL//9u70mCriyuvSVU+pGYykyrzhWSmEhRnqubD7KnKVDKTmm+pVM2kNICyPGQXERRlEQRlF0UQF8CVRaMYI4q4A6KAgCCgbPLgvn1/iJqZqnyYshKmT/ftvvct993uc/r+u/u+86v6Ke+9u53b3b9//0+fJXbtgO+ukgWDqeNSzr5K1vi06ZJTafsobFh4l/KOCg30/dq2iXUxaofP6yVvABlkkDeAGbQMoyyQcvZ1NRWSEXy/f8dHx9Qx533LgtqI/vw6YPn+ld5f27ZbQIwiLj+/pxZ/KYs4dVzgu6tkBj51XMrZV8kuPyax7tDRYPaRPv9KFSMLGuj7tU3yjdDukDaiP7+nE7OUtYMRCagLpFCw9PbgCwsjALblSDBsf+8D5UF7+KGgNmLZ+elZ5cG8927vr21bfidWEW974y3lwXzqSfL4hdYALKjj0vzkExWtwUkdl3L2mXIkFejzDR1GpJfr09JdciptH4VN69YqD+befd5f27b8TqzaoWPmoZg4dQxDawAjcVAXCBQJlpuExf43CVTaCgAkaZQrSIxh2xtvetkk+LARQ9PtYI7/zT0UcbW5+Mcq4nBh87G5T1nEqeNS2CTsDz6emHlnChI/OXBBYgzr59zmZZNAsY9Cs7kXN0o+X9cU4J5WvgB3rNoBN9Rqc3+WPIahNYCROKgLpFDXqDIFS6kLxMY+SNIo15IMQ1/HhD5sxBCOKKTYTp/s/bWhjZNNC75YRbxwvL+cPH6hNQAL6rhAaIQ8JjxyPPh4YuZdoSXZGu/vXzd9UkUT6yq9rszxvtBAn69baME3M7iNWPo63k9ZOxiRgLpA2nfv9VbZ3DdtBaBh0Xx1R3bS73FLy5bNSgRf3RHcRgxlwPLE0Zdz40d5T/CBRu5SBI+eCGYfhb4SfFIWceq4mESB07XBxxMz7zqOnFA3ASuWen1vue7EmstNHBPUPgpNgs+WLV5fF47E5bq7Z0FwG7H01TkrZe1gRAJyJt+Ond56G/qmrQA0rlqe72Tysd+FvuExdQzy7u7gNmJZN2NKvtvBRa+v23D3XHXxP3MhqH1YdtW1Kk/EHbeSxy+0BmBBHZf6WbpUSGvw8cTMu84z59VmRMxln+/d3dKtPO8zpga1j0LIjJbXhQ0DZ/m7ErxmctO9akVwG7GEa6V0DLy2kzyGoTWAkTjImXzPv2AKloZeWFgBgDiuSpRcaFx9f8XqhLnaiGX93FnqIl3b4PV1TS/dhvag9mHZ3fml/Py5qTeRx+hVZQsAACAASURBVC+0BmBBHRf47uTNhfguQ48nZt51NbSpjdqs6V7fu6u2Xt1czLsjqH0U6jqfjQ/e7/d1dWmqR9YFtxHLlhd/q7yjL7xAHsPQGsBIHN4y+TwH+/qgrQCYoquv+y26agqWHh+4YGkWNqJtWLJIeepOnPb6urkp4/IX/6+C2keyId/toLsDv4FJWcQp49Ktu+SI7zD0OGLnHcxdHzcBvQlrTXoWxdoLaR+FUKRZ2iA00OfrQmFs6VkUmh3aRrQNnpIDU9YORiQgZ/JZBvOHoK0AwJ2YvCN70a8X07ZgaRY2YgnJPXIT++FH3l7TeM8sLv6xirgcX5M8hO92kLKIU8YFEq5sg/lD0HbeVcKL2S7WmvSerV4V3D4sQfMqUWC/Jd+esmXbtuA2osfXU/JQytrBiATkQO5li9UG4eNPgi8srAC07nhN3ZFt8hvHWDdzqlXB0ixsxLJp/aPKO7rrPW+v2VWvjs4gBiy0fRQWarXhyzmkLOKUcTHloypQY9IHrUtIzZqeD2Vo8/bebbv2qA2CWHuh7cOyWxfYn3mz19c18XM7dga3EcuOo5+oDf7yxeQxDK0BjMRBDuTOwMtFWSA29sHmxncms2r5k8+gLVOwNAsbsaxEJjNkfcqL/8J5we2j0Id3NGURp4yL8XJFWD7KZd6ZZKbT5729d6UyaDH2YSkL7I+/UVYR8FlBQGfQtu0uf0Maq3b48o6mrB2MSEBdIJCpJr1czV3BFxZWADoqcDEymXwVbpFX8XIOutvBc895e02o+ya/75XlW+TFKuLAgnd0D2n8QmsAFpRxgcx45eV6LPg4UuYdlIBRtQwHLmfkQtsuOVnYR6FpeeaxgoCpoXfwSBQ2YgjXSuUdpWV5p6wdjEhACuQ2ja3914nzQVsBMEHXHruZVCoGBmsjlm1vvaOOxx/f6O01ofODvPivKx8DE6uIA8FDIy/UhF6wKYs4ZVyMl2tr5bxcFFpXEHhojYqBft9fN5PmjRvUjcXb7wa3j0LIYpbH4+fqvb2m6aLxyZkobMSwcN2keUdT1g5GJCBtAPWdTAXrVVFoKwCmn7HHlmc6zgNiJGOwEUsoYeO7nIPpo/vkE8Hto9CHdzRlEaeMS8uzz6rN88vbg48jZd5BGzi5WfPYz9iUjzqQbvkoYMOye73Hh5sWeUKzY7ARy0J91W7SGIbWAEbiIAVyZ+TloiwQG/u6Wy/mW55N8vbehUyvB6OwEctKlKRwaZEXs4iDh0ZuZDduII1faA3AgjIuzRvX571cu4KPI2XeVaLlWcPihRUpvYSxj8Kmtf4rRNTdYt8iL2bt8BE7n7J2MCIBZYH4ymaqFK03gOCSnzT2cu6mG7wlbPiq9eTLRixN701x5+3rNZs3bUo+kw/owzuasohTxiULLxeFzhUENm/y9t71s/NeLrH2QttHoe8asTKxRGg0aHUsNmLpo3pGytrBiASkTL6MvFyUBWJrn+lM0ThwZwpbmnpVxGrvPm3EsLs9X7B32kRvrwlV/G07r8Qs4h3HT5G9oymLOGVcsvByUWg770xnikcf9vbeddMm5AuMfxHcPgp1lyhf9VWha5DUIqHVsdiIpQ/vaMrawYgEpEw+h1iuEHQRAChJoso5+GlMb7qL7PTbXYRiI5a5KTXKO1qma4ctG+9bpu5+PzoWhX1YmtjRufjY0ZRFnDIuEG9rG8sVgtYVBMQcll7g+5Z7eV/TXWTKuCjso7D1tdfV9eGZp728Xuepc/nyUXdFYyOWPmJHU9YORiQgZfL9Nt/T8PnKerkoC8TWvsZVy9Wm5PDHXt7b9Bd+74NobMQSCjbLi3W9n2K3pnbamQtR2IclxCFJj8Qt+NjRlEWcMi51t0xUXq72S8HHkTLvOs+cV5sSMad9vG9XXau6qbijfJH0LOyjELRPekeFFvp4vY5DR9Vme9WKaGzEsuX551UYzG9fIo1haA1gJA5SILeuyv7azuALiioAUATatsCoDRtXLMnXBzsejY1YNiy6S23YxB24j9eru22adYeUmEUcSI0dTVnEseNiYrkm1wQfP+q869IdL8Sc9vG+nSc/UxvKRfOjsI9C4x1dsdTL67kW7I9ZOyD+mdp9KmXtYEQCygJxieUKQRcB8N3xon7BHLVpOlvey5WVjVjCHbfczIo7cOpryYSbifkOKRY1sGIWcSA1djRlEceOi2ssVwhaJ5DJjhejxJwe46UWasehI2rTdP/KKOyjEDz80psptNDH67l2SIlZO0zsqLiGUsYwtAYwEgcpk0/Hcnk6NvVNFwHw3fECemDaermyshFL4x310A/YdEixrB0Zs4gDqa3AUhZx7LiYVoCejk0rQacEMlPTjd7xIos+wK72YenbO+paOzJm7YBrJjV2NGXtYEQCUiaf58QJ33QRAKhHpmq6rSe/b48+wBXukJJJNp9H76ipHTl/djT2UQjt7GwTWkrZF1oDsMCOSyFxonwrwFB0mXc++6Fn0QfY1T4sC95RP/2Amzfka0e+Y1c7MmbtcE1oKWVfaA1gJA5SILc+/mrwUzrFN10EoP3AYXVRWr2K/L4FL1dl+wC72oilT+9ox9ET+bigJdHYRyE12SdlEceOi4/jr0rTKYFseT7e9yi944XxclWwD7CrfRRCL3Rf3lHo1S7X2ocfRWUjhl0NbeoaMWs6aQxDawAjcVAWCARx+yye7JsuAgC9JeUd2b30fsBZdkjJQuR8dLzQbN+7zykzMGYRB0KJC5UI9Tp6/EJrABbYcYGkMVUeBB8AX2k6JZCtW6s2Jnvp/YCz6pCS1bry2Q+44Z4FytP66dmobMTQJEJNwSdCpawdjEiAzuRrv5QvgeGvQLBvughAV65FbdrunEF+3yw7pGRSzsFjP2Coi+hSGyxmEQdCkVtKwe+URRw7LrpAMJSRCj1+Puadqfn5Or3mZ1YdUrJaVz46XmiCNsvNZF1LVDZiCcX1VSkkXMHvlLWDEQnQmXy6CK7HFmG+6SIA3R1fqgKsU28iv2+hQ8qaqGzE0vQDXryQ/FqwUXK5+Mcu4m2v01r+pSzi2HEptAh7M/j4+Zh35iZg2zby+zYsvjuTDilZrSvoEkXteKEJ2iw3TJ1fRmUjltSWfylrByMSoAO5j59Um4Kl9wRfSL4EoO7m8V5aMGXVBxhjI4Y++wGbi79lBfzYRRwubHKzvxbXDjFlEceOS9Pa1WpTsO/D4OPnY96Zjkge1nsWfYBd7aMQvhO12af1Ay60pJwQnY1YQgtJ6R09fgo9hqE1gJE40IHc+sIXaR9gjAD4El/TB9iDR8C3jRhixLcUTQ9My4t/7CJO7Qecsohjx0Vf+GLtA+w673xqoa+bUJ/2Uag9/tR+wJib0Ni1g9oPOGXtYEQC7AKBeBd51/v0U8EXki8B8NWg3mdMkG8bsYTepOr4hdYPGDzG6q73ZFT2YWkuTLNx3tGURRw7LvWzZ6obrVxz8PHzMe86juVPQ5bdS3pPONr0FYbi0z4KXWN+S9GEoTjcaMWuHcY7+jouFCJl7WBEAg7kLhCSHOQd2X5aALYpDbJ3X3Q2Ymn6Ade10l5n7iz1Oucbo7IPS2rsaMoijh0X11iuEHRKIKttUDcB8+4gvWdWfYBd7aPQVz/g9v0HVSLamgeisxHLwZxAxogE6EDuxzequ5e33gm+kHwJgC+bIPvXV10w3zZi6VqCoRTrbpmkLv5tn0dlH8kmk813CTV+oTUAC8y4wLjHXj3Add4Zm6ZPIr2nKUUl1lpM9lFo6n4ut6v7WYqgydKTKDQ6NhvRNr35trLpicfRYxhaAxiJA7tAsipXQKGrALT85jfKq/nS70jva7xctQ3R2YilGW+Cd9TUvppsX/sqdhGnjnfKIo4Zl67aei/eskrTdd7lJo0l10Q1Xi4P5ZZ824elr/EGTZbeMqHRsdmIH29aea2UtYMRCdCB3J48QpWkqwC07nhN3ZFt3kR6X0iWoNR3qqSNWMJdqkv2bn/EVL+PXcSBlFpnKYs4ZlyyrJFJoXMFAQ9dkUw28ZM4j1Al7cOykEBG8/g2b9qkbs537IzORiypzQdS1g5GJEAHcuuYsPq24AvJlwD4aFEF2XtS8G4eH6WNWEJGMzWz2fS/XGTf/zJ2EQcWOkG4x3ymLOKYcfEVE1ZpOieQLbxL3RCLOY59Tx9rrFL2UZgzmc34mE/QZLnGhEbHaCOG1JjPlLWDEQlQcTzd/+PlyKPSdBWAjiPHlXdixVL8otYFsufeHqWNWPrwTkAPT/n93r8yOvsohJZmqh3cTtT4hdYALDDjAh4cOY82xdsGDjPvYE5LL7Bln9p+55EHL3ul7KOwfs7tTolf/X6/K/L9loVGx2gjhpiQmN72hdYARuJAbQBbLiov161Tgi8inwIA/Sqp8SpwDOijJESlbMSyfR89PqkaA7mBmPikYvtCawAWmHFpee45tVn+3cvBx83nvIM+2dQEskKc7cHo7KPQlH469in6NUxP4Vr7nsIpaEfd9MnKO9p6ETWGoTWAkTgwC6TzbE5tlObPDr6AfAqA6W9MiFcxR1zr1kZpI5bUeBUgpuxBCiLe9vYutbHduB41fqE1AAvMuDRvWK82Su/sCj5uPuedj7JYJq5arLXY7KOwad0aclksTFx1CtpRf9edasw/q0ONYWgNYCQOVCD3R8eUN2jlsuALyLcAUCvxm0SSjI64Msvm0/Eqs/A1ygo9YO3bQqUg4h36aPuB+1DjF1oDsMCMizkqPXgk+Lj5nHc+2j9CclRWcdVZrisTIuGQwFFMbCeiFLQDwo1cj7aL7QutAYzEgQrk3r1XebkefTj4AvItABC7R4lXaXn22UyPuDLL5tPxKpPGyhhQzGtgCm2nIOKY5JZi+0JrABaYcfGRLJEFnRPIEIWKiynjqieOuZwbf2MmcdVZrivQQun5f+451PNNoe25s6K1EUtMckuxfaE1gJE4UIHcr7yqFvSWLcEXkG8BoBZxblr/qPJyvbs7WhuxrJsxRXlHm7tQzy+UDvosSvuw7GrsUB6K26ahxi+0BmCBGRf4juQNVlNn8HHzOe+gHBaliDOsKTmHZkyN0j4KQQulw2D9Y6jnY4tJp6AdLVs2K4fBqztQYxhaAxiJAxXIvXWrmrTbXwm+gHwLAOWODNh433K1gTz8cbQ2Ylm/YI7awJ05j3q+qZXWaF8rLQURl97RCaMERzt7R1MWcddxkV4u+T2NQnuRs6JzAllDu9rAiTmOeb/O0+fVBvLuuVHaR2HHoaNqA7dqOer52PJcKWgHXEOlM+XZragxDK0BjMSBWSBNjz2ivFy73gu+gHwLAHg15eb2lVdR71nYJF2I1kYsQcDl5lYIuutzsRf/FEQcWDfzZuUddfRspSziruMCXj+spzRrOieQwU3AeNxNALDj0JH8JmlFlPZRCDeM8ghXaCPm+ebEaavbiVMK2tG2a0/eO/ooagxDawAjcaACuTP2cmGJEQDq8bY5Jm3pjtZGLOEIB3u8DV4/zMU/BREHgudGbvxPu3lHUxZx13HpPF2rvFwL5wUfr0rMO3O83djh/H6QFS03Ahtwx6RZ2Icl9Xgbe0yagnbANRTrHU1ZOxiRALNAsvZyYYkRAEo3EB+JElnYiCUlwQXi/lSixPxo7aMQPDcY72jKIu46LsbL5VAIPBQx8w6SgKQunrSPcdU0tSSRiRJZ2IclNcEFusbIsJz3PojWRiy1dxRz9J+ydjAiASqQm5gMkBUxAkDpVeqjVEoWNmJJKXHTfiDf+Hy1WyHpFEQcaLyjjvXtUhZx13HJ2stFISqBbPUqtVE5cNj5/ailUrKwj0JKiRtsr+0UtKPgHXVvqpCydjAigXMgd8eXyss1pabqArmBlFZuPoolZ2EjlpQi19DeCtNKLgURB0IXEEwh4JRF3Dm+VhcCf/754ONViXlHaeXmo1hype2jkFLkGttKLgXtkN7RyTWqrWqnW6/klLWDEQmcN0imJlM2vW4pxAgAFIAG+6CBuev7mXZpyFpgWdmIJaXNnWl0/+KL0dpHodngPuG+wQ2tAVg4b5Ae34jeIGVNVAKZnuPi/67v56NdWqXto7BQA9S9zV1u6k354vzuG6QUtIOywQ2tAYzE4XxEqruArFgafOFUSgCgFZwUnLbPnZ5nugE8+UT0NmJovKNz3Df/5uLv2Cs1FRE33UAc49tSFnHnI1IdJxl5FxDsvMPeBADr59xGKkCfhX0UgufftQsQEDRYHpHe4t6eMxXtaFyxRK0LcW11tS+0BjASBzqOB1nUM0tiBUA3Hnftz4g9BgxhI4aU439okyY9AGKjFKt9FEJClNwcO/bHTlnEXcfF9D09G3fyGHbeQeyfinNd5fRe8hhwSv4Y0NHLlaV9FGKP/0GD5boScyd2G7HENg9IWTsYkYDjePrS9Gd0vCMr1EfcE72NWEIpB0y9O2wLsFRE3Hgqprl5KlIWcddxgV6uGM96CGLmHbYloKmPODObLiBY+yg03UCERro8j9J3PhXtGIzxw4xIwHE8fYktdA2xcZQ2clnaiCU2mJtSKDkFEZc2IjY4KYu4y7hgN8ihiEogQxa6NsljyDZyWdlHoW7nBhm9Ls8zhZIdN44hbMRyMMYPMyKBcxzP/SurOo4HCG15MPXu6u+4VcXx5JqjtxHLprUP5rMV91s/x3RJmDgG1SotBRGX44844kxZxF3GBXtEHoqoBDJT726UU707yPyVm5yHHozaPgq7LjSp8b9zhtPzQINVq7Rno7cRy8EYP8yIBBzH05dtr7snc6h+sKNVqzNEsdOsbcSyefMm51Z5heSR26K3j0Jzc+QQ55iyiLuMSzvyIheK6Pjh2flkDrHhsX1OofvQ5ujtw7JwEzjaSR8LySNvRm8jloMxfpgRAXKjr/vB119c4jieXjR3ZA59ObvqWjIvAk2xEUtTDPoZ+2LQpt1RFcfxAFHhEV1fXv5szMh/EsvxytB64IAr4TP/6euvrccFsj+xGbIhmGX8cPMzT2daBJpiH4WmGHRdq/33qfuPI06cUtEObHhEd67p8vma4d8PLQaMRHFh3MjGhtshXsXuWI6Skh+CWAEwmWfz7rB+jqmRt/SeJGzEsn3fh861DqH0i7z4iw1S7PZRiEmQat3+inzOhTEjrg+tB7bI1Qz/NXzmr95503pcQmTIU4idd80bNziXOzI18va518jL2j4KMbUO6+fOUpvGc/VJ2Iila+kxCDeApCG4hofWA0aiyNWMbJKTrt7ujsy4qhfMCb5gKikAmHInkDAi43gQPYRD2Igl9DmVG92F86yfU7j4vxS9fRRiSiQ1Pbw22Q1g1+OPWo8LttRFKGLnHWxw5U2AmPO2z4E+sJgM+RD2UQjaKOfAbrvkOkqXjFA2YgnHvy6hVfrEiTeADDRyNSPek5Pu4xNWkw4brBqKFAGATD55kWtst3p81s3cfdiIYXdLt/ICT59s/Rwt/O2790ZvH4WYIuk6q/rCqOH/EFoPbJGruf4f5YZ+2SLrccEWuw1FdPzw7vyN4KMPWz+nbvok5f1puRi9fRSCNsp5I7TS5vFdDe2orOqQNmLpmlzZceSE3gDuCa0HjEQhNoBPyQuzZQP7wRLHA2xYvFAtyOOnrB5v+oA6VroPaSOW0CZPXrDav7D7Lpcsyn+XJ5OwD8uu2nrnTil1t06Wz8mN/sV3QuuBLY4NH/4X0gs8c6r1uJhOF7UNwcepkvOu49hJ5SEXc97m8d3tl9QmB9F6MoR9FBY6JdldP0AvXL7LGGzE0jV+uO3td5Vu1Ix4MrQeMBJFrmb4XfKO7Hm744rBEscDdPVahWpzFULkXDPBXb2poe3D0jV0oLv1orqLrxn5eWgtcMWFmhGX4LNftIhZoh7lhSB23hmv1e23WD0+VHmcEOvK9QTJeFORYTUpaYdr/LC+FosN4LzQWsBIFLXjRoxwWWCDJY5HLjDH44rCpiiXjI1YupQ7gQu+3BRNdm8fF8o+CutmTLEueK3jKcVm6khoLXDFhXEjjspNvUXcWrcukDwju04XVKLjh2GzO2ms9WY3VHmcEOsKbhjlZteyrRvEDLvGU4a2EUvTKUVcY20e3/TwQ2oDOHbk8NBawEgUtWOv/xfpYr/3bqtJZ47yHLK4QpIiAKY6u2Xmam7qTU7HojHYiKVLbS7I3pOiP3dWMvZRCGvJNnRAFwAWm6ltobXAFbmakS9KO98vXxDcHOUtttOZGEiZd/Vzb88fd5fPXMXUHA1tH5agjXLTYnncTe06lZJ2uFaR0LHD58YN/+fQWsBIFKdG/fK76s58itWkq7vV3rsRAykCYGrX3Ve+dl13c5fycNxq9z3GYiOWLgkvcCTuWlMxtH0UmjaCFnG1usvBhXEjl4fWAlfkakaskB7y7dvL2tn2dj47GtHOKxQp887UrjtUPhwEOlzI79Gx61BI+yiE5DGV8NJd/ntcuUx9j0KLU7IRQ9NG0PFa/MmvfvWXobWAkTDqLQs7m+zPWyYFXyxZCAAEq9sG9Hd+elbdvTk2gQ9tI5YQFykv6A8/VPaxroHfMdhHoSkDYrE51olDYjM1IbQOuCI3dvhE23E14RSIMkChSJl3Lglh+iivfc/7ydhHYcPCu1SozKeflX2sSRw635iUjVhCfV2bbHBTj/fm8dwJhEFDy73zrWpQwZGWy3FxDKQIQHfnV5dz42+U8TzlYtdMDUCLDVFMNmJpNrwWtQCxfZVD2kdh+3sfqLmwtnxfV+3hEJup/witA644N+bXP7f1kDetXa02OXv3BR+fLOadS/9aUwPQYkMUi30U6g1vuVqAPfoqCy1OyUYs9bFu54nTAz4OrtVSf8XcCa0DjMTR+Vj+DvSDAwNOOhOkOkiOcYCQySfvQOvbBnyczshqefHF5GzEUJausMx2bVqnCh3DxigV+yjsPF1rXSy9fvZM+djTN/z3X4XWAVecrRn+19LO2eX7O5sit6fPBx+fLOYdePNsbgh7ZEcPgthhYMu2bVaJHdAuTnq5Zk1PzkYsTfhImSTL9vf3528yV/MGkEHD5y+9oDw0218ZeOGaY5w0SsD4EICGZYtVDMqR4wMv3DUP5D0c5QPiY7MRy/o7blWb4zJN782RzydnkrIPy+6OL6yynru7fn85N2GU4OjLi6+44huhdcAVLw0f/s3cxNHy84MtA9qps2I7st3kUEiZdzDXbUJC4GhTbqLvnJGUfRTqxCfYvAz0OF1UHTQ4NRuxNKVgymyOW1/erh63dQtvABk0/P79PVZZaE0PPTiojnGAzU89qTa9ZZq0Q89gl7p4MdmIpa572H7gcMnHyIs/eDjG34j2cKQm4nI+zMpvjnPNJR9jLv6zb0tWxJvm3V72JgD+Ju0UNwyhxyWreWc85HATMMDmuP3AoSAlYKj2UWjqHpbps9664zV1XRIanJqNWJrwkYfWDPi44ioMoTWAkTj+cPaUVbYrHGmpY5za4AslKwEwJRoGKAUjYwUn5D0hyFiVkDZi2bx5U1nPcedndflEmvLHhLHZR6HJXhwgCxT+ptddaA3Aov3BfD3IQ0dL23nwiJW+xEbqvIONvdwcnytdCgbWjvTkbNmcnH1YKr0cdRm8xwPpZfPGDdalpmKzEUsd21cufKRYX0JrACNxfP3VVyrWYmbpIq09YlUGyTEOEOodlqtfZoqblrmjjdVGLE2dxA3rSz7GHPeseSA5+yg0nuPXdpZ8jLn4b3omWRH/fNuzZW8CwHsu58nTTwUflyznXaNFWEjThsfUJuetd5Kzj0KoCapOTEoXzTf1NI+5t4+MwUYMTfhImdhqKKgus4Ub2pLVDkYkgAWiawpBG6P+JhwcZclNzqzBc4wjF2S+VRcUeS61IEHgbWJaYrURS9PzdPHCko9peUHFl9q2N4rJPgrN8dUAmx7TavDd3cmK+P8ePKDm/gCdhGzDKGIjdd6ZxLBt20o+Bm4s5SYH0SM7tH0UmpjpEkXEpcMBCuuDw8Gi1WCMNmIJSS8qfKSl3793iU2frhcIdoXWAEbigAUCxzMDxXPBEc9gPMYBmniuEnFOkPlrE7gbs40YmrqQ0yaWfIwp/4HMAA5pH4WFY8/lJR+j40a7zpxPVsT/r01lag7U2ktri01R5JhInXflygHBJqdO12AtU/ctRvso1AmFkPTQ399NfCwxbjRF7ShX/NrEjQpt4Q0ggwxYIKZWW4kM39ZX6QG5IehDABofuE9tYvYd7Pfvpq7VroHrWsVsI5YQNjCQ5xiKaMujns/qkrQPS534AGWE+vu7TBLI15i82P37ZEX8T3/8o8rwHSDJx5RSKpMtHhup8w6ON+UmZm7/heSNJ2fmzUnaR2Hbrj0Deo7b932oNjlCe1O1EUvjMRfX3P7+bjKFxTWbN4AMMmCBmLpVJe5Wm9atsapPFBt9CIBp1VRic2wKuZ7MtpCrTxuxbFy+pOTdqoxn0YW0B8iEjNk+LKV3R4dV1PU9yjG9cRfNT1rEYVyg1Ik6xjzVx044xtLHVeXqRcZGcviILn8Dm+N+4qZNq8kVS5K0j0Ioeq0LGff3d7PJseimE6uNWEILSXktXre237+bUxVxzU5ZOxiRABZI17l8tubsmf1OOnMXX9sQfIFkLQBQsb7UgpQZbbrGWcaFXH3aiGXhbnVHn7+ZWmgW3UJitY/CxtX3G6HuM6d2vmGyy1MWcRiX5sfz2Zqvv9HHTn1j2fjg/cHHI8S8K3T5ONvnb7BmQp6qhFxXoJUy2aHEzaF2OEDLyVRtxLKrtn7AAthQM1Jnl6esHYxIAAsEjqFM0G1rz3iUwl381EF3Fw+E7gWl4pz0Jsem60PMNmI50N1q29vvqr8RO8ekKOJA3Q6s+Zmn+/zNlLgQm6aURRzGBWwoVSoJkmDkDcLL24OPR4h5Zzo7vL2r798Cn6qEXlemO0w/m2NTV/UMrXNMaBsxlKcHM/o/PYBY0eKkxJS1fsDGJQAACZlJREFUgxEJ9AJpWLJIHeUcOdFj0pm7eEIpj1D0IQDSy6d7UvbKSDPZngPUCUzBRizhLrRUdrjxDpbpMBOzfRR2fPxJ/pi3bzeI4mPTlEUcxqWz6Di7j535LjBQTin0eISYd7rUT39ePpPtWVu6TmDs9lEImtlfdjhoLGit9A4S66qGthFL8Jj3d3oAHankWhPXam1faA1gJA69QMwF+5VXey5UfRdPvJCHoC8BaFh2r1qQH37U4/cmAaSfO/zUbMRQ3q1On6QuZL36JYPHVN7FI1vAxWAf6bvp+PKyapU2SiZ9mN/rsIF84kTKIi5PD4pjPYsu2CrRZZS8eYLvIvR4hJh3nSdO93t6YPrcTp8c7FQl9LoyJwS9+iVDJQq5ySG0gIvFRix1q7feZaTg2lz8+5S1gxEJ9ALRsW69M68Kd/HZ16qKRQBMPbutW83v5ObntmkmHiN1G7HUWdIwf/Tvuhrb1QXu5vGkBJAY7KPQ1Hn76Jj5nelxmo+NTFnEzemBsEWdHhzva+cAdSJjppfTA0gEEWtAakRjh/k9VAyQWrt6VdL2Uai7BIGGFm+Cob9tufqJqdiIpWlA0Ov0AFoGFsdGpqwdjEigF0h3U6e6k4f+lfmstZ7u+MF5Fy8XpHa9LywsSIhdGShxJjUbsdQJDcV38iBQPso4xGAfhdDiq3e9s5YtW3rUjUxZxPW4mKLH4uJt7NSZnFu2ZPqd+6KveWfKSBUlNEDMbKnEmdTswxI2fTqhAbKC9e+Nw6FXKFKKNqK/G3l6MKbH6YGsqqBPDpq7jH2hNYCRAa699topQ4cO/Wm5x11zzTXzhg0bdp3gMvHvH9i8dvECgbt1VRD6kPxZx//BEWjoRRFSAGDzCwWPi7190N1CuuM3PVMVNmJpkoTA25c/AtQZsD4ucKHto7B9/0G1fu5ZoOYRXPTyAe66+0MlRbySugHQ46K7woBt2psDMYFSS/b3Xz8zdvqadzpJRmdCg5YYr2A/JYJSs4/C5meeUTcJz78gfzZeQaG1PhwOMdiIZcPSe9T6yRfRb99/qEf8n7aPphCM2PEtIcjThZB/LMT53wd6oHjcT8TjnoJ/i/9/Xzx+u80bFC8QHbSsPTe6ij/0fQ29IEILgA5aho0fbHR0EHfxsVfqNqLFKp/UAF4O6UmeMFpS36mmbh+W8sZh+mTl5Th9Xno1zLFX/mi8QiJecd0AmNMDYYsOh+g4ekLYWluIcUvw5MDnvOuxHsS/dahNf8lBKdpHoT5ZgSQy0FTtSW5+4vGqsRHLtjfeUtfifDch7UkujsXnDeAggRDlzeWEXIj3AiHmk4qe02rz2sULBC7Y0IgaysFAvJtpTN2afaui2ARAezkgBV8nxkCdr9ClcWIQOShlIYV87izT59NXb+QY7KOwedMm40XXDe5bX/pdD/uo+lAKldQNQI+bR2GTtFPYqJOmmjdvCv79xzDvitcErBF5U71rT9XYh6X0iC+YYxIbZCmycf56I8dgI/q7gT70fa7F42QLzmL7KPrASAQ2Qi7+/ojgjUU/t3zve9/7s3KvDQvk0iU1mVQ8j+rTqAn1zPTfUiPY1ds+CnXtLs2OD/ZXnY0YQh1J3fZNctJYWd6iWuyjsLuhzWRKq3qaU4SId/Wwz4dGlNCEiukGoHhcwCZdv0x5/yZJ20N//zHMO1loH2K68t8NrBVYM9ViH4WgocWa2vTw2qqzEUtdS1QTrs297aNqBCMBWN7Jrxd38iOKfu4YMmTIt13fa/EVV3wjVzPyUcHzF2pGPgA/u3/i6sSpUb/87vmaEc9dqBnRen7siMmhP09MyI2+7ge5cSM+vDBuxCe144b/V+jPExPOjfn1v4n1dFDMm0/Pjrv+77J63yx1AwC2gY1g67ma4T/BvEa1AtYErA1YI7BWQn+emABaKjVVaCtobOjPEwsWi2svXIPhWgzX5MV8La4+CMH9mRDpw4KHini4OBbH4ShnQtHP7ZX83AwGIxxYNxgMBmMQoD8hF6J9dfHPQrh/DHfz8O+hQ4eKhw/bmeVnZDAYcYF1g8FgMBKGEOxpQpTPCG4R//55/tdXip/rxM/f6fXYlULMbxBcdfXVV1+T/adlMBgxgHWDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBiMpXHvttVOGDh360+LfXXPNNfOGDRt2neAy8e+qqFov7Px78b9vQpurail1UY3j1BvVOG6A3usutbEcLLoBqMY5WK1jpVGNY6aRunYw4sC3xGSZLibTx8XFYsXvfiJ+9xT8W/z/+8WdBVKGsOMTYc8lwVeHDBlyVejPQ0W1jlNvVNu4XdHPuktsLAeVbgCqbQ5W81hpVNuY5ZG6djBiQ+9uAfnWUJOK/t4a5pP5hbCrJvRn8IlqHafeqLZx0yhedymO5WDRDUC1zcFqHiuNahuzYqSuHYyI0FvIxb8fEbyx6OcWcKOH+XT+kO9y8Avx//k//OEP/zb056GiWsepN6pt3DSK112KYzlYdANQbXOwmsdKo9rGrBipawcjIvRzJ79e3FGMKPq5Y8iQId8O8+m84kr4z1VXXfXnwt7DoT8MFVU8Tr1RVeOm0esuPrmxHES6AaiqOVjlY6VRVWNWjNS1g5ERxGT4GUx+wUNFPFwcJ1DiKGdC0c/tWX9uDErYCtwu7gR/Jf6+Nv/Qb4jf/SHoh/WAVMfJBflxW5P/sSrGTaOfY5xoxnIw6QaAtSOdsbJBNesGIGbtYCSGfoT8x3BXAf8eOnSo+NOwneE+nR8IQfhPYcu/wr9/9KMf/Y2waVfoz0RFNY5Tb1TjuGn0EvHkxnIw6AagGudgtY6VRjWOWTFS1w5GJBB3DtPEhDkjuEX8++dFv18pJtUN+TiKqkihh0BZuFMSti6tlqywahyn3qjSceuz7lIay8GkG4AqnYNVOVYa1ThmgNS1g8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwWAwGAwGg8FgMBgMBoPBYDAYDAaDwcgG/w9y3cgw27lOYAAAAABJRU5ErkJggg==\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Gridify example, forced height\n",
|
|
"# If the default gridify layout is not fitting well, you can force the height\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.set_grid(height=2)\n",
|
|
" \n",
|
|
"# Gridify example, forced width\n",
|
|
"# … or the width\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")\n",
|
|
" figure.set_grid(width=2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# You can also specify a grid directly in the constructor\n",
|
|
"with replot.Figure(\n",
|
|
" grid={\n",
|
|
" \"width\": 2, \n",
|
|
" \"height\": 1, \n",
|
|
" \"grid\": [\n",
|
|
" ((0, 0), \"a\", (1, 1)),\n",
|
|
" ((0, 1), \"b\", (1, 1))\n",
|
|
" ]}) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"b\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# You can also specify a grid directly in the constructor\n",
|
|
"# Setting the grid to False ignores the groups you may have defined.\n",
|
|
"with replot.Figure(\n",
|
|
" grid=False) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"b\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Note that if we use legend, xlabel or ylabel with subplots,\n",
|
|
"# they will be set identically on every subplot\n",
|
|
"with replot.Figure(xlabel=\"some x label\", ylabel=\"some y label\") as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\", label=\"cos\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\", label=\"sin\")\n",
|
|
" figure.set_grid([\"aç\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# You can avoid it by passing dict for these arguments\n",
|
|
"# they will be set identically on every subplot\n",
|
|
"with replot.Figure(xlabel={\"a\": \"some x label\", \"ç\": \"\"},\n",
|
|
" ylabel={\"a\": \"\", \"ç\": \"some y label\"},\n",
|
|
" legend={\"a\": False}) as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\", label=\"cos\")\n",
|
|
" figure.plot(np.sin, (-10, 10), group=\"ç\", label=\"sin\")\n",
|
|
" figure.set_grid([\"aç\"])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Saving figures"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"metadata": {
|
|
"collapsed": false,
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# Save a figure to a file\n",
|
|
"with replot.Figure(savepath=\"/tmp/out.png\") as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"application/javascript": [
|
|
"/* Put everything inside the global mpl namespace */\n",
|
|
"window.mpl = {};\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",
|
|
" fig.send_message(\"refresh\", {});\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.imageObj.onload = function() {\n",
|
|
" if (fig.image_mode == 'full') {\n",
|
|
" // Full images could contain transparency (where diff images\n",
|
|
" // almost always do), so we need to clear the canvas so that\n",
|
|
" // there is no ghosting.\n",
|
|
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
|
|
" }\n",
|
|
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
|
|
" };\n",
|
|
"\n",
|
|
" this.imageObj.onunload = function() {\n",
|
|
" this.ws.close();\n",
|
|
" }\n",
|
|
"\n",
|
|
" this.ws.onmessage = this._make_on_message_function(this);\n",
|
|
"\n",
|
|
" this.ondownload = ondownload;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_header = function() {\n",
|
|
" var titlebar = $(\n",
|
|
" '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
|
|
" 'ui-helper-clearfix\"/>');\n",
|
|
" var titletext = $(\n",
|
|
" '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
|
|
" 'text-align: center; padding: 3px;\"/>');\n",
|
|
" titlebar.append(titletext)\n",
|
|
" this.root.append(titlebar);\n",
|
|
" this.header = titletext[0];\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"\n",
|
|
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
|
|
"\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.figure.prototype._init_canvas = function() {\n",
|
|
" var fig = this;\n",
|
|
"\n",
|
|
" var canvas_div = $('<div/>');\n",
|
|
"\n",
|
|
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
|
|
"\n",
|
|
" function canvas_keyboard_event(event) {\n",
|
|
" return fig.key_event(event, event['data']);\n",
|
|
" }\n",
|
|
"\n",
|
|
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
|
|
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
|
|
" this.canvas_div = canvas_div\n",
|
|
" this._canvas_extra_style(canvas_div)\n",
|
|
" this.root.append(canvas_div);\n",
|
|
"\n",
|
|
" var canvas = $('<canvas/>');\n",
|
|
" canvas.addClass('mpl-canvas');\n",
|
|
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
|
|
"\n",
|
|
" this.canvas = canvas[0];\n",
|
|
" this.context = canvas[0].getContext(\"2d\");\n",
|
|
"\n",
|
|
" var 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);\n",
|
|
" canvas.attr('height', height);\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'];\n",
|
|
" var y0 = fig.canvas.height - msg['y0'];\n",
|
|
" var x1 = msg['x1'];\n",
|
|
" var y1 = fig.canvas.height - msg['y1'];\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;\n",
|
|
" var y = canvas_pos.y;\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\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
|
|
"\n",
|
|
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
|
|
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
|
|
" // object with the appropriate methods. Currently this is a non binary\n",
|
|
" // socket, so there is still some room for performance tuning.\n",
|
|
" var ws = {};\n",
|
|
"\n",
|
|
" ws.close = function() {\n",
|
|
" comm.close()\n",
|
|
" };\n",
|
|
" ws.send = function(m) {\n",
|
|
" //console.log('sending', m);\n",
|
|
" comm.send(m);\n",
|
|
" };\n",
|
|
" // Register the callback with on_msg.\n",
|
|
" comm.on_msg(function(msg) {\n",
|
|
" //console.log('receiving', msg['content']['data'], msg);\n",
|
|
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
|
|
" ws.onmessage(msg['content']['data'])\n",
|
|
" });\n",
|
|
" return ws;\n",
|
|
"}\n",
|
|
"\n",
|
|
"mpl.mpl_figure_comm = function(comm, msg) {\n",
|
|
" // This is the function which gets called when the mpl process\n",
|
|
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
|
|
"\n",
|
|
" var id = msg.content.data.id;\n",
|
|
" // Get hold of the div created by the display call when the Comm\n",
|
|
" // socket was opened in Python.\n",
|
|
" var element = $(\"#\" + id);\n",
|
|
" var ws_proxy = comm_websocket_adapter(comm)\n",
|
|
"\n",
|
|
" function ondownload(figure, format) {\n",
|
|
" window.open(figure.imageObj.src);\n",
|
|
" }\n",
|
|
"\n",
|
|
" var fig = new mpl.figure(id, ws_proxy,\n",
|
|
" ondownload,\n",
|
|
" element.get(0));\n",
|
|
"\n",
|
|
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
|
|
" // web socket which is closed, not our websocket->open comm proxy.\n",
|
|
" ws_proxy.onopen();\n",
|
|
"\n",
|
|
" fig.parent_element = element.get(0);\n",
|
|
" fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
|
|
" if (!fig.cell_info) {\n",
|
|
" console.error(\"Failed to find cell for figure\", id, fig);\n",
|
|
" return;\n",
|
|
" }\n",
|
|
"\n",
|
|
" var output_index = fig.cell_info[2]\n",
|
|
" var cell = fig.cell_info[0];\n",
|
|
"\n",
|
|
"};\n",
|
|
"\n",
|
|
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
|
|
" 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 + '\">');\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 dataURL = this.canvas.toDataURL();\n",
|
|
" this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\">';\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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\">"
|
|
],
|
|
"text/plain": [
|
|
"<IPython.core.display.HTML object>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"# or equivalently\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10))\n",
|
|
" figure.savepath = \"/tmp/out.png\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Some errors you might encounter"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "Second parameter in plot command should be a tuple specifying plotting interval.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-28-810be42c9f1a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid interval for plotting a function\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msin\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 253\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m\"__call__\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 254\u001b[0m \u001b[1;31m# We want to plot a function\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 255\u001b[1;33m \u001b[0mplot_\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_plot_function\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 256\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 257\u001b[0m \u001b[1;31m# Else, it is a point series, and we just have to store it for\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36m_plot_function\u001b[1;34m(data, *args, **kwargs)\u001b[0m\n\u001b[0;32m 531\u001b[0m raise exc.InvalidParameterError(\n\u001b[0;32m 532\u001b[0m \u001b[1;34m\"Second parameter in plot command should be a tuple \"\u001b[0m \u001b[1;33m+\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 533\u001b[1;33m \"specifying plotting interval.\")\n\u001b[0m\u001b[0;32m 534\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mx_values\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my_values\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 535\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: Second parameter in plot command should be a tuple specifying plotting interval."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid interval for plotting a function\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.sin, None)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "You should pass at least one argument to this function.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-29-bb8eaf706fb0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid plot call, no arguments given\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 242\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 243\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 244\u001b[1;33m \"You should pass at least one argument to this function.\")\n\u001b[0m\u001b[0;32m 245\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 246\u001b[0m \u001b[1;31m# Extract custom kwargs (the ones from replot but not matplotlib) from\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: You should pass at least one argument to this function."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid plot call, no arguments given\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "Group name cannot be longer than one unicode character.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-30-8b04957bf3f0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# Invalid group argument, groups are one unicode character long\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"abc\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mplot\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 247\u001b[0m \u001b[1;31m# kwargs\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 248\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mkwargs\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[1;32mNone\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 249\u001b[1;33m \u001b[0mkwargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcustom_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0m_handle_custom_plot_arguments\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 250\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 251\u001b[0m \u001b[0mcustom_kwargs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m{\u001b[0m\u001b[1;33m}\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36m_handle_custom_plot_arguments\u001b[1;34m(kwargs)\u001b[0m\n\u001b[0;32m 490\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"group\"\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 491\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 492\u001b[1;33m \"Group name cannot be longer than one unicode character.\")\n\u001b[0m\u001b[0;32m 493\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m\"group\"\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0m_DEFAULT_GROUP\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 494\u001b[0m raise exc.InvalidParameterError(\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: Group name cannot be longer than one unicode character."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid group argument, groups are one unicode character long\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"abc\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "Grid cannot be an empty list.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-31-c89b5aaa14ef>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;32mwith\u001b[0m \u001b[0mreplot\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"a\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapply_grid\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mapply_grid\u001b[1;34m(self, grid_description)\u001b[0m\n\u001b[0;32m 142\u001b[0m \u001b[1;31m# Check that grid is not empty\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 143\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrid_description\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 144\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mexc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mInvalidParameterError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Grid cannot be an empty list.\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 145\u001b[0m \u001b[1;31m# Check that all rows have the same number of elements\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 146\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mrow\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mgrid_description\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: Grid cannot be an empty list."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid grid, no grid provided\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.apply_grid([])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"ename": "InvalidParameterError",
|
|
"evalue": "All rows must have the same number of elements.",
|
|
"output_type": "error",
|
|
"traceback": [
|
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m Traceback (most recent call last)",
|
|
"\u001b[1;32m<ipython-input-32-c6ca6527d69a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mfigure\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcos\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mgroup\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"a\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m figure.apply_grid([\"a\",\n\u001b[1;32m----> 5\u001b[1;33m \"ba\"])\n\u001b[0m",
|
|
"\u001b[1;32m/home/phyks/Code/replot/replot/__init__.py\u001b[0m in \u001b[0;36mapply_grid\u001b[1;34m(self, grid_description)\u001b[0m\n\u001b[0;32m 147\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrow\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m!=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrid_description\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 148\u001b[0m raise exc.InvalidParameterError(\n\u001b[1;32m--> 149\u001b[1;33m \"All rows must have the same number of elements.\")\n\u001b[0m\u001b[0;32m 150\u001b[0m \u001b[1;31m# Parse the ASCII art grid\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 151\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgrid\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mgrid_parser\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mparse_ascii\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mgrid_description\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
"\u001b[1;31mInvalidParameterError\u001b[0m: All rows must have the same number of elements."
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Invalid grid, not a rectangular one\n",
|
|
"with replot.Figure() as figure:\n",
|
|
" figure.plot(np.cos, (-10, 10), group=\"a\")\n",
|
|
" figure.apply_grid([\"a\",\n",
|
|
" \"ba\"])"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "physique",
|
|
"language": "python",
|
|
"name": "physique"
|
|
},
|
|
"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.5.1"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|