{
“cells”: [
{

“cell_type”: “markdown”, “metadata”: {}, “source”: [

“# Nuken”, “n”, “Sometimes matplotlib just doesn’t give us the tools we need to animate stuff. This block is a way to work around that.n”, “n”, “Matplotlib.axes.Axes.quiver does not have a way to dynamically set the location of arrows, only the angle. In this example, we work around that.”

]

}, {

“cell_type”: “code”, “execution_count”: 1, “metadata”: {}, “outputs”: [], “source”: [

“%matplotlib notebookn”, “import numpy as npn”, “import matplotlib.pyplot as pltn”, “import animatplot as amp”

]

}, {

“cell_type”: “markdown”, “metadata”: {}, “source”: [

“Lets first construct our data. “

]

}, {

“cell_type”: “code”, “execution_count”: 2, “metadata”: {}, “outputs”: [], “source”: [

“E0 = np.array([1, 2])n”, “E0 = E0 / np.linalg.norm(E0)n”, “n”, “phi = np.array([0, np.pi / 7])n”, “n”, “f = 3n”, “t = np.linspace(0, 2 * np.pi, 100)n”, “n”, “ES = E0[:, np.newaxis] * np.exp(n”, “ 1j * (t + phi[:, np.newaxis])n”, “) # fancy array boardcasting”

]

}, {

“cell_type”: “markdown”, “metadata”: {}, “source”: [

“Now, we animate the data.”

]

}, {

“cell_type”: “code”, “execution_count”: 3, “metadata”: {

“scrolled”: false

}, “outputs”: [

{
“data”: {
“application/javascript”: [

“/* Put everything inside the global mpl namespace /n”, “window.mpl = {};n”, “n”, “n”, “mpl.get_websocket_type = function() {n”, “ if (typeof(WebSocket) !== ‘undefined’) {n”, “ return WebSocket;n”, “ } else if (typeof(MozWebSocket) !== ‘undefined’) {n”, “ return MozWebSocket;n”, “ } else {n”, “ alert(‘Your browser does not have WebSocket support.’ +n”, “ ‘Please try Chrome, Safari or Firefox ≥ 6. ‘ +n”, “ ‘Firefox 4 and 5 are also supported but you ‘ +n”, “ ‘have to enable WebSockets in about:config.’);n”, “ };n”, “}n”, “n”, “mpl.figure = function(figure_id, websocket, ondownload, parent_element) {n”, “ this.id = figure_id;n”, “n”, “ this.ws = websocket;n”, “n”, “ this.supports_binary = (this.ws.binaryType != undefined);n”, “n”, “ if (!this.supports_binary) {n”, “ var warnings = document.getElementById("mpl-warnings");n”, “ if (warnings) {n”, “ warnings.style.display = ‘block’;n”, “ warnings.textContent = (n”, “ "This browser does not support binary websocket messages. " +n”, “ "Performance may be slow.");n”, “ }n”, “ }n”, “n”, “ this.imageObj = new Image();n”, “n”, “ this.context = undefined;n”, “ this.message = undefined;n”, “ this.canvas = undefined;n”, “ this.rubberband_canvas = undefined;n”, “ this.rubberband_context = undefined;n”, “ this.format_dropdown = undefined;n”, “n”, “ this.image_mode = ‘full’;n”, “n”, “ this.root = $(‘<div/>’);n”, “ this._root_extra_style(this.root)n”, “ this.root.attr(‘style’, ‘display: inline-block’);n”, “n”, “ $(parent_element).append(this.root);n”, “n”, “ this._init_header(this);n”, “ this._init_canvas(this);n”, “ this._init_toolbar(this);n”, “n”, “ var fig = this;n”, “n”, “ this.waiting = false;n”, “n”, “ this.ws.onopen = function () {n”, “ fig.send_message("supports_binary", {value: fig.supports_binary});n”, “ fig.send_message("send_image_mode", {});n”, “ if (mpl.ratio != 1) {n”, “ fig.send_message("set_dpi_ratio", {‘dpi_ratio’: mpl.ratio});n”, “ }n”, “ fig.send_message("refresh", {});n”, “ }n”, “n”, “ this.imageObj.onload = function() {n”, “ if (fig.image_mode == ‘full’) {n”, “ // Full images could contain transparency (where diff imagesn”, “ // almost always do), so we need to clear the canvas so thatn”, “ // there is no ghosting.n”, “ fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);n”, “ }n”, “ fig.context.drawImage(fig.imageObj, 0, 0);n”, “ };n”, “n”, “ this.imageObj.onunload = function() {n”, “ fig.ws.close();n”, “ }n”, “n”, “ this.ws.onmessage = this._make_on_message_function(this);n”, “n”, “ this.ondownload = ondownload;n”, “}n”, “n”, “mpl.figure.prototype._init_header = function() {n”, “ var titlebar = $(n”, “ ‘<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ‘ +n”, “ ‘ui-helper-clearfix"/>’);n”, “ var titletext = $(n”, “ ‘<div class="ui-dialog-title" style="width: 100%; ‘ +n”, “ ‘text-align: center; padding: 3px;"/>’);n”, “ titlebar.append(titletext)n”, “ this.root.append(titlebar);n”, “ this.header = titletext[0];n”, “}n”, “n”, “n”, “n”, “mpl.figure.prototype._canvas_extra_style = function(canvas_div) {n”, “n”, “}n”, “n”, “n”, “mpl.figure.prototype._root_extra_style = function(canvas_div) {n”, “n”, “}n”, “n”, “mpl.figure.prototype._init_canvas = function() {n”, “ var fig = this;n”, “n”, “ var canvas_div = $(‘<div/>’);n”, “n”, “ canvas_div.attr(‘style’, ‘position: relative; clear: both; outline: 0’);n”, “n”, “ function canvas_keyboard_event(event) {n”, “ return fig.key_event(event, event[‘data’]);n”, “ }n”, “n”, “ canvas_div.keydown(‘key_press’, canvas_keyboard_event);n”, “ canvas_div.keyup(‘key_release’, canvas_keyboard_event);n”, “ this.canvas_div = canvas_divn”, “ this._canvas_extra_style(canvas_div)n”, “ this.root.append(canvas_div);n”, “n”, “ var canvas = $(‘<canvas/>’);n”, “ canvas.addClass(‘mpl-canvas’);n”, “ canvas.attr(‘style’, "left: 0; top: 0; z-index: 0; outline: 0")n”, “n”, “ this.canvas = canvas[0];n”, “ this.context = canvas[0].getContext("2d");n”, “n”, “ var backingStore = this.context.backingStorePixelRatio ||n”, “tthis.context.webkitBackingStorePixelRatio ||n”, “tthis.context.mozBackingStorePixelRatio ||n”, “tthis.context.msBackingStorePixelRatio ||n”, “tthis.context.oBackingStorePixelRatio ||n”, “tthis.context.backingStorePixelRatio || 1;n”, “n”, “ mpl.ratio = (window.devicePixelRatio || 1) / backingStore;n”, “n”, “ var rubberband = $(‘<canvas/>’);n”, “ rubberband.attr(‘style’, "position: absolute; left: 0; top: 0; z-index: 1;")n”, “n”, “ var pass_mouse_events = true;n”, “n”, “ canvas_div.resizable({n”, “ start: function(event, ui) {n”, “ pass_mouse_events = false;n”, “ },n”, “ resize: function(event, ui) {n”, “ fig.request_resize(ui.size.width, ui.size.height);n”, “ },n”, “ stop: function(event, ui) {n”, “ pass_mouse_events = true;n”, “ fig.request_resize(ui.size.width, ui.size.height);n”, “ },n”, “ });n”, “n”, “ function mouse_event_fn(event) {n”, “ if (pass_mouse_events)n”, “ return fig.mouse_event(event, event[‘data’]);n”, “ }n”, “n”, “ rubberband.mousedown(‘button_press’, mouse_event_fn);n”, “ rubberband.mouseup(‘button_release’, mouse_event_fn);n”, “ // Throttle sequential mouse events to 1 every 20ms.n”, “ rubberband.mousemove(‘motion_notify’, mouse_event_fn);n”, “n”, “ rubberband.mouseenter(‘figure_enter’, mouse_event_fn);n”, “ rubberband.mouseleave(‘figure_leave’, mouse_event_fn);n”, “n”, “ canvas_div.on("wheel", function (event) {n”, “ event = event.originalEvent;n”, “ event[‘data’] = ‘scroll’n”, “ if (event.deltaY < 0) {n”, “ event.step = 1;n”, “ } else {n”, “ event.step = -1;n”, “ }n”, “ mouse_event_fn(event);n”, “ });n”, “n”, “ canvas_div.append(canvas);n”, “ canvas_div.append(rubberband);n”, “n”, “ this.rubberband = rubberband;n”, “ this.rubberband_canvas = rubberband[0];n”, “ this.rubberband_context = rubberband[0].getContext("2d");n”, “ this.rubberband_context.strokeStyle = "#000000";n”, “n”, “ this._resize_canvas = function(width, height) {n”, “ // Keep the size of the canvas, canvas container, and rubber bandn”, “ // canvas in synch.n”, “ canvas_div.css(‘width’, width)n”, “ canvas_div.css(‘height’, height)n”, “n”, “ canvas.attr(‘width’, width * mpl.ratio);n”, “ canvas.attr(‘height’, height * mpl.ratio);n”, “ canvas.attr(‘style’, ‘width: ‘ + width + ‘px; height: ‘ + height + ‘px;’);n”, “n”, “ rubberband.attr(‘width’, width);n”, “ rubberband.attr(‘height’, height);n”, “ }n”, “n”, “ // Set the figure to an initial 600x600px, this will subsequently be updatedn”, “ // 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-buttonsn”, “ $( ".ui-button" ).hover(n”, “ function() { $(this).addClass("ui-state-hover");},n”, “ function() { $(this).removeClass("ui-state-hover");}n”, “ );n”, “n”, “ var status_bar = $(‘<span class="mpl-message"/>’);n”, “ nav_element.append(status_bar);n”, “ this.message = status_bar[0];n”, “}n”, “n”, “mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {n”, “ // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,n”, “ // which will in turn request a refresh of the image.n”, “ this.send_message(‘resize’, {‘width’: x_pixels, ‘height’: y_pixels});n”, “}n”, “n”, “mpl.figure.prototype.send_message = function(type, properties) {n”, “ properties[‘type’] = type;n”, “ properties[‘figure_id’] = this.id;n”, “ this.ws.send(JSON.stringify(properties));n”, “}n”, “n”, “mpl.figure.prototype.send_draw_message = function() {n”, “ if (!this.waiting) {n”, “ this.waiting = true;n”, “ this.ws.send(JSON.stringify({type: "draw", figure_id: this.id}));n”, “ }n”, “}n”, “n”, “n”, “mpl.figure.prototype.handle_save = function(fig, msg) {n”, “ var format_dropdown = fig.format_dropdown;n”, “ var format = format_dropdown.options[format_dropdown.selectedIndex].value;n”, “ fig.ondownload(fig, format);n”, “}n”, “n”, “n”, “mpl.figure.prototype.handle_resize = function(fig, msg) {n”, “ var size = msg[‘size’];n”, “ if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {n”, “ fig._resize_canvas(size[0], size[1]);n”, “ fig.send_message("refresh", {});n”, “ };n”, “}n”, “n”, “mpl.figure.prototype.handle_rubberband = function(fig, msg) {n”, “ var x0 = msg[‘x0’] / mpl.ratio;n”, “ var y0 = (fig.canvas.height - msg[‘y0’]) / mpl.ratio;n”, “ var x1 = msg[‘x1’] / mpl.ratio;n”, “ var y1 = (fig.canvas.height - msg[‘y1’]) / mpl.ratio;n”, “ x0 = Math.floor(x0) + 0.5;n”, “ y0 = Math.floor(y0) + 0.5;n”, “ x1 = Math.floor(x1) + 0.5;n”, “ y1 = Math.floor(y1) + 0.5;n”, “ var min_x = Math.min(x0, x1);n”, “ var min_y = Math.min(y0, y1);n”, “ var width = Math.abs(x1 - x0);n”, “ var height = Math.abs(y1 - y0);n”, “n”, “ fig.rubberband_context.clearRect(n”, “ 0, 0, fig.canvas.width, fig.canvas.height);n”, “n”, “ fig.rubberband_context.strokeRect(min_x, min_y, width, height);n”, “}n”, “n”, “mpl.figure.prototype.handle_figure_label = function(fig, msg) {n”, “ // Updates the figure title.n”, “ fig.header.textContent = msg[‘label’];n”, “}n”, “n”, “mpl.figure.prototype.handle_cursor = function(fig, msg) {n”, “ var cursor = msg[‘cursor’];n”, “ switch(cursor)n”, “ {n”, “ case 0:n”, “ cursor = ‘pointer’;n”, “ break;n”, “ case 1:n”, “ cursor = ‘default’;n”, “ break;n”, “ case 2:n”, “ cursor = ‘crosshair’;n”, “ break;n”, “ case 3:n”, “ cursor = ‘move’;n”, “ break;n”, “ }n”, “ fig.rubberband_canvas.style.cursor = cursor;n”, “}n”, “n”, “mpl.figure.prototype.handle_message = function(fig, msg) {n”, “ fig.message.textContent = msg[‘message’];n”, “}n”, “n”, “mpl.figure.prototype.handle_draw = function(fig, msg) {n”, “ // Request the server to send over a new figure.n”, “ fig.send_draw_message();n”, “}n”, “n”, “mpl.figure.prototype.handle_image_mode = function(fig, msg) {n”, “ fig.image_mode = msg[‘mode’];n”, “}n”, “n”, “mpl.figure.prototype.updated_canvas_event = function() {n”, “ // Called whenever the canvas gets updated.n”, “ this.send_message("ack", {});n”, “}n”, “n”, “// A function to construct a web socket function for onmessage handling.n”, “// Called in the figure constructor.n”, “mpl.figure.prototype._make_on_message_function = function(fig) {n”, “ return function socket_on_message(evt) {n”, “ if (evt.data instanceof Blob) {n”, “ / FIXME: We get "Resource interpreted as Image butn”, “ * transferred with MIME type text/plain:" errors onn”, “ * Chrome. But how to set the MIME type? It doesn’t seemn”, “ * 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 takesn”, “ // 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-canvasn”, “mpl.findpos = function(e) {n”, “ //this section is from http://www.quirksmode.org/js/events_properties.htmln”, “ 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 bugn”, “ targ = targ.parentNode;n”, “n”, “ // jQuery normalizes the pageX and pageYn”, “ // pageX,Y are the mouse positions relative to the documentn”, “ // offset() returns the position of the element relative to the documentn”, “ 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 keysn”, “ * we need this to avoid circular referencesn”, “ * http://stackoverflow.com/a/24161582/3208463n”, “ /n”, “function simpleKeys (original) {n”, “ return Object.keys(original).reduce(function (obj, key) {n”, “ if (typeof original[key] !== ‘object’)n”, “ obj[key] = original[key]n”, “ return obj;n”, “ }, {});n”, “}n”, “n”, “mpl.figure.prototype.mouse_event = function(event, name) {n”, “ var canvas_pos = mpl.findpos(event)n”, “n”, “ if (name === ‘button_press’)n”, “ {n”, “ this.canvas.focus();n”, “ this.canvas_div.focus();n”, “ }n”, “n”, “ var x = canvas_pos.x * mpl.ratio;n”, “ var y = canvas_pos.y * mpl.ratio;n”, “n”, “ this.send_message(name, {x: x, y: y, button: event.button,n”, “ step: event.step,n”, “ guiEvent: simpleKeys(event)});n”, “n”, “ / This prevents the web browser from automatically changing ton”, “ * the text insertion cursor when the button is pressed. We wantn”, “ * to control all of the cursor setting manually through then”, “ * ‘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 eventn”, “}n”, “n”, “mpl.figure.prototype.key_event = function(event, name) {n”, “n”, “ // Prevent repeat eventsn”, “ if (name == ‘key_press’)n”, “ {n”, “ if (event.which === this._key)n”, “ return;n”, “ elsen”, “ this._key = event.which;n”, “ }n”, “ if (name == ‘key_release’)n”, “ this._key = null;n”, “n”, “ var value = ‘’;n”, “ if (event.ctrlKey && event.which != 17)n”, “ value += "ctrl+";n”, “ if (event.altKey && event.which != 18)n”, “ value += "alt+";n”, “ if (event.shiftKey && event.which != 16)n”, “ value += "shift+";n”, “n”, “ value += ‘k’;n”, “ value += event.which.toString();n”, “n”, “ this._key_event_extra(event, name);n”, “n”, “ this.send_message(name, {key: value,n”, “ guiEvent: simpleKeys(event)});n”, “ return false;n”, “}n”, “n”, “mpl.figure.prototype.toolbar_button_onclick = function(name) {n”, “ if (name == ‘download’) {n”, “ this.handle_save(this, null);n”, “ } else {n”, “ this.send_message("toolbar_button", {name: name});n”, “ }n”, “};n”, “n”, “mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {n”, “ this.message.textContent = tooltip;n”, “};n”, “mpl.toolbar_items = [["Home", "Reset original view", "fa fa-home icon-home", "home"], ["Back", "Back to previous view", "fa fa-arrow-left icon-arrow-left", "back"], ["Forward", "Forward to next view", "fa fa-arrow-right icon-arrow-right", "forward"], ["", "", "", ""], ["Pan", "Pan axes with left mouse, zoom with right", "fa fa-arrows icon-move", "pan"], ["Zoom", "Zoom to rectangle", "fa fa-square-o icon-check-empty", "zoom"], ["", "", "", ""], ["Download", "Download plot", "fa fa-floppy-o icon-save", "download"]];n”, “n”, “mpl.extensions = ["eps", "jpeg", "pdf", "png", "ps", "raw", "svg", "tif"];n”, “n”, “mpl.default_extension = "png";var comm_websocket_adapter = function(comm) {n”, “ // Create a "websocket"-like object which calls the given IPython commn”, “ // object with the appropriate methods. Currently this is a non binaryn”, “ // socket, so there is still some room for performance tuning.n”, “ var ws = {};n”, “n”, “ ws.close = function() {n”, “ comm.close()n”, “ };n”, “ ws.send = function(m) {n”, “ //console.log(‘sending’, m);n”, “ comm.send(m);n”, “ };n”, “ // Register the callback with on_msg.n”, “ comm.on_msg(function(msg) {n”, “ //console.log(‘receiving’, msg[‘content’][‘data’], msg);n”, “ // Pass the mpl event to the overridden (by mpl) onmessage function.n”, “ ws.onmessage(msg[‘content’][‘data’])n”, “ });n”, “ return ws;n”, “}n”, “n”, “mpl.mpl_figure_comm = function(comm, msg) {n”, “ // This is the function which gets called when the mpl processn”, “ // 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 Commn”, “ // 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 realn”, “ // web socket which is closed, not our websocket->open comm proxy.n”, “ ws_proxy.onopen();n”, “n”, “ fig.parent_element = element.get(0);n”, “ fig.cell_info = mpl.find_output_cell("<div id=’" + id + "’></div>");n”, “ if (!fig.cell_info) {n”, “ console.error("Failed to find cell for figure", id, fig);n”, “ return;n”, “ }n”, “n”, “ var output_index = fig.cell_info[2]n”, “ var cell = fig.cell_info[0];n”, “n”, “};n”, “n”, “mpl.figure.prototype.handle_close = function(fig, msg) {n”, “ var width = fig.canvas.width/mpl.ration”, “ fig.root.unbind(‘remove’)n”, “n”, “ // Update the output cell to use the data from the current canvas.n”, “ fig.push_to_output();n”, “ var dataURL = fig.canvas.toDataURL();n”, “ // Re-enable the keyboard manager in IPython - without this line, in FF,n”, “ // the notebook keyboard shortcuts fail.n”, “ IPython.keyboard_manager.enable()n”, “ $(fig.parent_element).html(‘<img src="’ + dataURL + ‘" width="’ + width + ‘">’);n”, “ fig.close_ws(fig, msg);n”, “}n”, “n”, “mpl.figure.prototype.close_ws = function(fig, msg){n”, “ fig.send_message(‘closing’, msg);n”, “ // fig.ws.close()n”, “}n”, “n”, “mpl.figure.prototype.push_to_output = function(remove_interactive) {n”, “ // Turn the data on the canvas into data in the output cell.n”, “ var width = this.canvas.width/mpl.ration”, “ var dataURL = this.canvas.toDataURL();n”, “ this.cell_info[1][‘text/html’] = ‘<img src="’ + dataURL + ‘" width="’ + width + ‘">’;n”, “}n”, “n”, “mpl.figure.prototype.updated_canvas_event = function() {n”, “ // Tell IPython that the notebook contents must change.n”, “ IPython.notebook.set_dirty(true);n”, “ this.send_message("ack", {});n”, “ var fig = this;n”, “ // Wait a second, then push the new image to the DOM son”, “ // 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 = thisn”, “ 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 ‘focusablen”, “ el.attr(‘tabindex’, 0)n”, “ // reach out to IPython and tell the keyboard manager to turn it’s selfn”, “ // off when our div gets focusn”, “n”, “ // location in version 3n”, “ if (IPython.notebook.keyboard_manager) {n”, “ IPython.notebook.keyboard_manager.register_events(el);n”, “ }n”, “ else {n”, “ // location in version 2n”, “ 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+entern”, “ if (event.shiftKey && event.which == 13) {n”, “ this.canvas_div.blur();n”, “ event.shiftKey = false;n”, “ // Send a "J" for go to next celln”, “ 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 forn”, “ // 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 outputn”, “ 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,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAE44SURBVHhe7d0HeFRV3sfx/6QTSAEChEAIoYbeuyAqXVREUQTrrq66oqLrquiq4K5iedfVtWDBthYUQRQVEESadJBuKKGGEkKAdNLnnXPmDoSQhCRkJjO538/zXO+Zc28CGcPNL6darDYCAAAA0/AyzgAAADAJAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAE71ySefiMViOXv4+PhI48aN5a677pIjR44Yd5XNgQMH9OdQn7MyLV26VH9edXaGVatWyeTJkyU5OdmoOWfgwIH6AABXIgACcImPP/5YVq9eLYsWLZJ77rlHZsyYIf3795eMjAzjjqrTtWtX/XdTZ2dQAXDKlCnFBsB33nlHHwDgSgRAAC7Rvn176d27t1xxxRXy3HPPyeOPPy779++X7777zrjD9XJzcyUvL0+Cg4P1302dXa1t27b6AABXIgACqBIqcCkHDx7U5+3bt8t1110ntWvXloCAAOncubN8+umn+lpp4uLidHdyy5YtJTAwUBo1aiTXXHONbNu2zbjDztHN+9lnn8nf/vY3fZ+/v7/++KJdwI6u5pIOB9Waqf7Oqktb/Z1btGgh9957ryQlJRl3iO76/fvf/67L0dHRZz+H488qrgv41KlT8te//lX/Hf38/KRZs2by9NNPS3Z2tnGHnfo8EyZM0F9TmzZt9NffqVMn+fHHH407AKB4BEAAVUIFL6VevXqya9cu6du3r+zYsUP++9//yrfffqtbxe6880555ZVX9H0lOXr0qNStW1deeuklWbBggbz99tt6nGGvXr305y1q0qRJcujQIXn33Xflhx9+kPr16xtXzmnYsKHuEi58zJ07V7cQqqDlsHfvXunTp49MmzZNFi5cKM8++6ysXbtWLrvsMt26qNx9993y4IMP6rL6uhyfr6Tu5qysLN1K+r///U8effRR+emnn+TWW2/V78Po0aONu85R19966y15/vnnZfbs2VKnTh25/vrrZd++fcYdAFAMKwA40ccff2xVj5o1a9ZYbaHImpaWZv3xxx+ttuBnDQoKsiYkJFjHjh1r9ff3t9qCmfFRdsOHD7cGBgZak5OT9ev9+/frz6U+Z0ny8vKsOTk51pYtW1ofeeQRo9ZqXbJkif7YAQMGGDXnOK6pc3EyMjKsPXv2tNqCofXAgQNG7fkKCgr013fw4EH9ub7//nvjitX66quv6jr19y/q8ssv14eDLZjqe2fOnGnU2L388su63hY0jRqrft2gQQNramqqUWPV76eXl5d16tSpRg0AXIgWQAAuobp8fX19xRb6ZOTIkRIeHi7z588XW4CRX3/9Va666iqJjIw07rZTLYCZmZm6xawkagzfiy++qFsMVXepav1T5z179khsbKxx1zk33HCDUSqb/Px8ufnmm/XnmjdvnkRFRRlXRBITE+W+++7Tf2/156qvz3G9uD+7LNR7UbNmTbnxxhuNGjv1XiiLFy/WZwfVWqjeUwf1fqpWTUfXOgAUhwAIwCVUl+b69etl06ZNutt269at0q9fP33t5MmTutu1qIiICH1W10uiukmfeeYZGTVqlO7SVV2w6s9RY+HOnDlj3HVOcX9OaVTAU13Ls2bN0uMSHQoKCmTIkCG6W1dNaFHBbN26dbJmzRp9vbg/uyzU16rCceGxhooKdSpkFn0vVPd3UWpsY0X/fADmQAAE4BJq7Fz37t11iCoawlSIOXbsmPHqHBUUlbCwMH0uzueffy633367bgUcOnSo9OzZU/85hSdiFFY0WJVGTeCYPn26fPDBBzrsFaYmrWzZskVeffVVPcZPTeTo0aNHsYGsPNTHHz9+XA3PMWrsVGujau0s7b0AgLIiAAKocqr7V3V9OgKfg2o1VDNbHTOGi6MCnWrxKkxNjCjvItNFffjhh3rtPjW5wtH9WpgjSBb9s9977z2jdI7jnrK0yqn3Ij09/YLlcdR7oajrAHCpCIAAqpxaF1CNn1Pj2b744gs9NlDNfFVBTrXChYSEGHdeSI0nVDuDvP766zpEqhY5tSyMWpqlotSYQ9X1q7qoBw8erLt1Cx9KTEyMNG/eXJ588km9qPXPP/+sl2RRs4WL6tChgz6/8cYb+nNv2LBB0tLSdF1RqjWzY8eOcscdd8h//vMf+eWXX/R78NRTT8mIESNk0KBBxp0AUHEEQABVrnXr1nq3DHV+4IEH9Hg+1cWqdg9xrKFXEhWqVFicOnWqXv9PBTA1Lk+Fs4pSy8eo7taVK1fqZV6KHooKrGrMYatWrfTaf7fccovuplWBrSjVPayWn1H3qyViVFfxxo0bjavnU+sJLlmyRMaPH6/D7PDhw3XAfeyxx/TXBQCVwaKmAhtlAAAAmAAtgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAzrAMKtqA321XZgQUFB5dqzFQCqK/VjWu0cExERIV5etNugchAA4VYOHz4skZGRxisAgEN8fPwlbXEIFEYAhFtJSUmR0NBQ/aALDg42agHAvFJTU/UvxsnJyaXuiw2UBwEQbkU96NQDTgVBAiAA8FyEczCYAAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGQIgAAAACZDAAQAADAZAiBKtHz5crnmmmskIiJCLBaLfPfdd8aVki1btky6desmAQEB0qxZM3n33XeNKwAAwF0QAFGijIwM6dSpk7z11ltGTen2798vI0aMkP79+8umTZvkqaeekoceekhmz55t3AEAANyBxWpjlIESqRbAOXPmyKhRo4yaCz3xxBMyd+5ciY2NNWpE7rvvPtmyZYusXr3aqCldamqqhISESEpKigQHBxu1AGBePBfhDLQAotKokDdkyBDjld3QoUNlw4YNkpuba9QAAICqRgBEpUlISJAGDRoYr+zU67y8PElKSjJqzpedna1/uy18AAAA5yIAolKpruLCHCMMitY7TJ06VXdtOI7IyEjjCgAAcBYCICpNeHi4bgUsLDExUXx8fKRu3bpGzfkmTZqkx7U4jvj4eOMKAABwFgIgKk2fPn1k0aJFxiu7hQsXSvfu3cXX19eoOZ+/v78e1Fz4AAAAzkUARInS09Nl8+bN+lDUMi+qfOjQIf1atd7dfvvtuqyoGb8HDx6URx99VM8E/uijj+TDDz+Uxx57zLgDAAC4AwIgSqRm73bp0kUfigp2qvzss8/q18eOHTsbBpXo6GiZN2+eLF26VDp37iz//Oc/5b///a/ccMMNxh0AAMAdsA4g3ArrXQHA+XguwhloAQQAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEAAAwGRYBxBuhfWuAOeIS0yXuZuPyKb4ZDmafEYC/XykXUSw3NG3qbRpyL81d8ZzEc5AAIRb4UEHVK6NB0/LKwt2ytr9p4ya83lZRB6+qpU8PKilUQN3w3MRzkAAhFvhQQdUjpPp2fLs3B3y09Zj+rWPLekNaFVPBrdtIE3qBEpaVq7M3XJU5m1L0Nf/eV07ua1PU12Ge+G5CGcgAMKt8KADLt2vO4/L47O2SlJ6jm7hG9MtUiYObikNQ2oYd5zz9pI4efXnXeLv4yW/PXGl1AvyN67AXfBchDMwCQQAqon8Aqu8NH+n/OmTDTr8tWpQS3548DJ5+caOxYY/5a8Dm0vnyFDJziuQ6b/tM2oBVHcEQACoBtKz8+TezzbIu8v26td/6hctcydcJu0iQvTrklgsFrnfFgKVuZuPCp1CgDkQAAHAwyWmZcmYd1fLL7GJ4ufjJa/f3FmevaatBPh6G3eUbkDLevrjjqVkyd4T6UYtgOqMAAgAHuxI8hm5+b01EnssVcJq+cvXf+kto7o0Mq6WTQ0/b+nRtLYurz9wWp8BVG8EQADwUPuTMuSmd1frc6PQGjLrvj7SpYk9yJVXi3q19PngyUx9BlC9EQABwAPFn8qUW95fo1sAm4XVlG9s4a+p7VxRUXXtH3vwZIY+A6jeCIAA4GESUrJk/PS1kpCaJS3q15Kv7+0jEaHFz/ItqwbBAfp8Mj1HnwFUbwRAAPAgaoHn8dPXyKFTmXpB5y/u7lUpa/cF+tknjGTl5eszgOqNAAgAHiIzJ0/u+mS97D2RIQ1DAnT4c7TcXSpH1+/Wwyn6DKB6IwACgAfIyy+QB7/cpANa7UBf+dwW/iLrBBpXL11eAev/AWZCAAQAN6cWZ578ww5ZvDNRb9k2/Y4e0tyYtVtZGte+tDGEADwLARAA3Nz7y/fJ52sOicUi8sbYztItqmJLvZTGx8v+46BTZKg+A6jeCIAA4MYWxx6Xlxbs1OVnrm4rw9o31OXK5pj8EeDDjwXADPiXDgBuKi4xTR7+arOo7XnH9Woif7os2rhS+U5n2Jd/qR3op88AqjcCIAC4oZTMXLn70w2Snp0nPaPryORr2hlXnONEWrY+hwURAAEzIAACgJvJL7DKg19tkgMnM/UWb9PGdxU/J3fNnki3B8B6tSpnWRkA7o0ACABu5o3Fe2T57hNSw9db3r+9m9StdekLPV8MLYCAuRAAAcCNLN2VKG/+ukeXp47uIO0iQnTZ2eJPndFn1eIIoPojAAKAmzh8OlMmfm2f9DG+VxMZ1aWRccW51DqDB0/ZdwJpWremPgOo3giAAOAGsvPy5YEvN0lyZq50bBwiz17T1rjifIlp2ZKVWyDeXhZpxILQgCkQAAHADbyyYJdsiU+WkBq+8va4ruLv421ccb4DSfbWP9X96+vNjwXADPiXDgBVbMnORPnwt/26/H9jOlXqHr9lsfeE0f0bRvcvYBYEQACoQompWfLYN1t0+c6+TWVw2wa67Eq7ElL1OSY8SJ8BVH8EQACoIgUFVnlk5mY5mZEjbRoGy5PDY4wrrhWbkKbPrRsQAAGzIAACQBV5b/k+WRl3Uq/399a4LhJgO7uamgG8yxEAaQEETIMACABVYPuRFPn3wl26POXadtK8Xi1ddrXjqdmSciZXzwBuUb9q/g4AXI8ACAAulpWbL498vVnyCqwyvH24jOne2LjielsPJ+tzC1sArYoWSABVgwAIAC6mlnzZk5gu9YL85YXrO4jFYjGuuN7Wwyn63CnSNTuOAHAPBEAAcKHf9iTJRyvtS768cmNHqVOzavfe3WK0AHaKDNVnAOZAAAQAF0nJzD275MutvZvIFa3r63JVURNA1OLTSqfGBEDATAiAAOAiU37cIQmpWRIdVlOeGtHGqK06B05mSmpWnvj7eDEDGDAZAiAAuMDi2OPy7e9HRA33U7t9BPr5GFeqzoYDp/S5faMQtoADTIZ/8QDgZKrr96k523T57suipVtUbV2uauuNANijaR19BmAeBEAAcLLnf/xDr7fXLKym/G1Ia6O26q0/cFqfe0a7RyAF4DoEQABwol93HpfZvx/WXb+vjunoNmvtJaZlyf6kDP336hZFCyBgNgRAAHCS1KxcmfRt4a5f9wla6/fbW/9iwoMlpIavLgMwDwIgADjJy/N36q5fNevXnbp+lXX7T+pzz6Z0/wJmRAAEACdYt/+UfLH2kC5PHd3B7bZZW7nXHgD7NK+rzwDMhQAIAJVM7fX75LdbdXlsj0jp3cy9Qtbx1CyJS0zX4//6NAszagGYCQEQACrZ20viZN+JDL3X76ThVb/gc1Er45L0uUOjEAkJZPwfYEYEQACoRDsTUmXa0r26/Py17dwyYK2Ms3f/9mtB6x9gVgRAAKgkBQVWPes3z3Ye3LaBDGsfblxxH2r/X0cLYL/mBEDArAiAAFBJvlofL5sOJUtNP295/rp2YlGD7NzM3hPpej9iPx8v6c4MYMC0CIAAUAmS0rPlpfmxuqyWfGkYUkOX3c2SnSf0uVd0HbebmQzAdQiAAFAJXvwpVlKz8qRdRLDc3ifKqHU/S3cn6vMVrevrMwBzIgACwCVatTdJvt10RC+r8sL1HcTH2z0frenZeXp9QmVg63r6DMCcCIAo1TvvvCPR0dESEBAg3bp1kxUrVhhXLvTJJ5/oMU9Fj6ysLOMOoPrJzsuXf3y3XZdv7RUlnSNDddkdrYpLktx8q0TVDdS7kwAwLwIgSvT111/LxIkT5emnn5ZNmzZJ//79Zfjw4XLokH13g+IEBwfLsWPHzjtUeASqqw+W79Nr/oXV8pfHhrrXdm9FLdllH/83sFU9/csZAPMiAKJEr732mvz5z3+Wu+++W9q0aSOvv/66REZGyrRp04w7LqR+qISHh593ANXV4dOZ8taSOF3+x9VtJKSG+y6qrJZ/WbrLPv5vIOP/ANMjAKJYOTk5snHjRhkyZIhRY6der1q1ynh1ofT0dImKipLGjRvLyJEjdcshUF298FOsZOUWSM/oOnJd5wij1j3tOJoqx1KypIavN/v/AiAAonhJSUmSn58vDRo0MGrs1OuEhATj1fliYmL0OMC5c+fKjBkzdNdvv379ZM+ePcYdF8rOzpbU1NTzDsATrNhzQuZvTxBvL4vbrvlX2MI/jutz/5ZhLP8CgACI0hX9oaa6kUr6Qde7d2+59dZbpVOnTnq84MyZM6VVq1by5ptvGndcaOrUqRISEnL2UF3MgLvLySuQ5+bu0GW15EtMeLAuu7NfjACodigBAAIgihUWFibe3t4XtPYlJiZe0CpYEi8vL+nRo0epLYCTJk2SlJSUs0d8fLxxBXBfH63cb0z88JOJg1oZte5LjVX841iqeNl+d7syhvF/AAiAKIGfn59e9mXRokVGjZ163bdvX+NV6VRr4ebNm6Vhw4ZGzYX8/f31zOHCB+DOElKy5L+L7b/UPDncvSd+ODha/7pF1Za6tfx1GYC5EQBRokcffVSmT58uH330kcTGxsojjzyil4C577779PXbb79dt+A5TJkyRX7++WfZt2+fDn5qBrE6O+4HqoOXF+yUzJx86dokVEZ3aWTUurdFsXT/AjgfARAluvnmm/XSL88//7x07txZli9fLvPmzdOzfBUVBtU6fw7Jycnyl7/8RS8Zo2YLHzlyRH9Mz549jTsAz7bx4GmZY+z4MeXa9uKl+lTd3OmMHFmzz777x+C2LMsEwM5iVf10gJtQs4DVZBA1HpDuYLiTggKrXP/OStlyOEXGdGssr47pZFxxbzM3xMvjs7ZKTHiQLJg4wKiFJ+G5CGegBRAAykC1/KnwV9PPW/4+zL13/Chs/jZ7K/2IDiWPxQVgPgRAALiI9Ow8PfZPefCqllI/yDO2N0zNypXf4pJ0eXh7un8BnEMABICLeGdJnCSmZUtU3UC5q19To9b9LY49Lrn5VmlRv5a0bBBk1AIAARAAShV/KlOmr9ivy0+PaCP+Pp6zi8b8bfZ1PEfQ+gegCAIgAJRCdf3m5BdI3+Z1PWoZFdVtvWz3CV0e1p7xfwDORwAEgBKoZV9+3HpML/vyj6vblrgNojtSiz9n5xVIdFhNadOQ7l8A5yMAAkAx1ApZ//rpD12+sWtjaRvhWctv/LDlqD5f0ynCo4IrANcgAAJAMX7adkw2HUqWGr7e8thQz1n2RUnOzJHle+zdv9d0pPsXwIUIgABQRHZe/tllX+69vJk0CPaMZV8cft6RoGf/qsWfmf0LoDgEQAAo4tNVByT+1Blb8POXvwxoZtR6jh+22Bd/Vt2/AFAcAiAAFKL2zn3z1zhd/tuQ1hLo56PLnuJEWras2mtf/PmajgRAAMUjAAJAIW8viZO0rDzdfXpD18ZGreeYt+2YFFhFOkWGSpO6gUYtAJyPAAgABrXo8/9WH9TlJ4fHiLeX582eVXsWK9fS/QugFARAADC8tmj32UWfL29Vz6j1HPuTMmRzfLIOrgRAAKUhAAKAzY6jKfLdZnvr2aThbTxy7TxH699lLcKkXpC/LgNAcQiAAGDz0vydYrXaZ852aBxi1HoOtXD1d0YAHN21kT4DQEkIgABM77c9SbLCdvh6W+TvQzxr0WeH3w+dlkOnMiXQz9uj9iwGUDUIgABMraDAenbR5/G9ojx25qyj+3dY+3CPW7oGgOsRAAGY2vztCbLtSIrU9POWB69sYdR6FrVzyY9b7Ys/X9+F7l8AF0cABGBaefkF8u9Fu3T57v7NpG4tz5w48WtsoiRn5uqdS/o2DzNqAaBkBEAApjX798Oy70SG1A70tQXAaKPW88zaeFifR3dt7JFrFwJwPQIgAFPKys2XN37Zo8sPXNFCggJ8ddnTJKZlydLdJ3T5xm6et3MJgKpBAARgSl+sPSRHU7IkPDhAbu0dZdR6HrX0S36BVbo2CZXm9WoZtQBQOgIgANNJz87Te/4qDw9qKQG+3rrsadTaf47u3xu7ReozAJQFARCA6Xy4Yr+cysiR6LCaMsaDu03V7OXdx9PF38dLRnZqaNQCwMURAAGYSnJmjkxfsU+XHxncSny8Pfcx6Gj9U2v/BXvoGEYAVYMACMBUPrCFv7TsPIkJD5KRHTy31UxNYnFs/cbkDwDlRQAEYBon07Pl45UHdHnioFbi5cFLpszffkxSs/KkUWgN6cfafwDKiQAIwDTeX75PMnPypX2jYBnazrP3y/1qXbw+39wj0qODLICqQQAEYApqvbxPV9tb/x4d3EosFs8NTftOpMva/adE5b4x3en+BVB+BEAApjBt6V7Jyi2QzpGhckXr+katZ5q5wT75Y6Dt62gYUkOXAaA8CIAAqr1jKWf0ws/K34Z4dutfbn7B2dm/qvsXACqCAAig2lOtfzl5BdKzaR25rIVnT5hYHJsoSenZElbLX66M8eyWTABVhwAIoFpTrX+OCRNq3T9Pbv1Tvlpvb8lUS7/4evAahgCqFk8PANXau6r1L79AekbXkT7N6xq1nin+VKYs231Cl8fS/QvgEhAAAVRbCSlZMmO9vfVv4lUt9dmTzVh3SKxWkf4tw6RpWE2jFgDKjwAIoNp6d5l97F+PprU9vvVPfR0zN9jD7PheTfQZACqKAAigWjqemiVfrrOPl1O7fnj62L+FfyRIUnqO1A/yl6vaePYi1gCqHgEQQLXkaP3rHlVb+np465/yxRp7mFVj/5j8AeBS8RQBUO0kqtY/Y92/hwe19PjWv7jEdFm976Te+ePmnnT/Arh0BEAA1c4HK/ZJdl6BdG0S6vHr/ilq8oei1v1rFMrOHwAuHQEQQLVyKiPn7K4fD17p+a1/Z3Ly5Zuzkz+i9BkALhUBEEC18vHK/ZJpC03tIoJlYOt6Rq3n+n7zEUnNypMmdQLl8lae//UAcA8EQADVRmpWrnyy6oAuT7iihce3/lmtVvl09UFdvq13lHipQYAAUAkIgACqjc9sYSktK09a1K8lQ9uFG7Wea+PB0xJ7LFUCfL1kTPfGRi0AXDoCIIBqITMnTz78bb8uP3BF82rRWuZo/buuUyMJDfTTZQCoDARAANXCjHXxegKIGit3TccIo9ZzqaVs5m87psu39WHyB4DKRQAE4PGy8/Ll/eV7dfn+gc3FpxoslKwCbV6BVbpF1Zb2jUKMWgCoHARAAB7vu01H5HhqtoQHB8joro2MWs+Vm18gX66zd//eTusfACcgAALwaPkFVnlv2T5dvrt/tPj7eOuyJ5u37ZgOtPWC/GV4+4ZGLQBUHgIgAI+2cEeC7EvKkJAavjK2mmyT9vFK+1I2t/aKEj8fHtMAKh9PFgAeS62TN22ZfezfHX2ipJa/jy57st8PnZbN8cni5+0l43uz7y8A5yAAAvBYK+NOytbDKXqdvDv6NjVqPZuj9e/azhESVstflwGgshEAAXisacvi9HlsjyZStxqEpYSUc0u/3NWvegRaAO6JAAjAI22JT9YtgN5eFj35ozr4bM0BvfRLz+g60i6CpV8AOA8BEIBHen+5febvtZ0ipHHtQF32ZFm5+fLl2kO6/Cda/wA4GQEQgMc5dDJT5m+3d5X+ZUAzffZ0czYdkdOZudIotIYMatPAqAUA5yAAolTvvPOOREdHS0BAgHTr1k1WrFhhXCne7NmzpW3btuLv76/Pc+bMMa4AlefD3/ZJgVVkQKt60qZhsFHruQpsX8z0FfYWTTX2rzrsZALAvfGUQYm+/vprmThxojz99NOyadMm6d+/vwwfPlwOHbJ3UxW1evVqufnmm+W2226TLVu26PNNN90ka9euNe4ALt3pjByZueGwLv+lv731Ty0Hs3/bQfnyxW9lzn/n6TpPsmz3Cdl7IkOC/H3k5h6RRi0AOI/F9uC0/R4NXKhXr17StWtXmTZtmlEj0qZNGxk1apRMnTrVqDlHhb/U1FSZP3++USMybNgwqV27tsyYMcOoKZ36+JCQEElJSZHgYM9v2UHle3PxHvn3ot3SJjxIpsQEydofN8ran36X4wdPiJeXRT7Y/h9pEuNZ28GN+2CNrNp7Uu7pHy1PX93WqAXseC7CGQiAKFZOTo4EBgbKN998I9dff71RK/Lwww/L5s2bZdmyZUbNOU2aNJFHHnlEHw7/+c9/5PXXX5eDB+37ml4MDzqUJuHoaRn89ipJyxeJXLRaAjbtMq7YRbQIl+sfHGG8unSjHhxulJxnx9EUufq/v+nZzMsfv0KPAQQK47kIZyAAolhHjx6VRo0aycqVK6Vv375GrciLL74on376qezadf4PXsXPz08++eQTGTdunFEj8uWXX8pdd90l2dnZRs35VH3ha+pBFxkZyYMO2tHEFElMTJaVs9fKrp83y5ozFkkc2ld8UtOl6fuzxaIGAjpBRNNsad0lUyZ9Y/szvJy7HMujX2+WbzcdkWs6Rcibt3QxaoFzCIBwBsYAolQWi8Uo2anfF4rWFVbe+1VXsnqwOQ4V/gCHD2atkvtfnCWr0jJk+D2DJPuKbro+dMMfTgt/yhXXn5Yn3z4k1sS+Yi1IN2orn1r4ee6Wo7qsun8BwFUIgChWWFiYeHt7S0JCglFjl5iYKA0aFL9ERXh4eLnuVyZNmqR/q3Uc8fHxxhXgHG9fb/Hv005S/Pz1fr//mTxKrntgmDSIqmfcYRfZOkJ+zPhc5mV9eUnHbU+G2T+hbwexeNWyl53gk1XGws9N60jHxqFGLQA4HwEQxVLduWrZl0WLFhk1dup14S7hwvr06XPB/QsXLizxfkUtF6O6NAofQHE+/G2/Pt/SM1L6j+giE978s3y27215f8v/yZ9eGCdt+7SSw7uPyeq5G8TXz7fCh4/3SbHk79B/lsX/Kn12hvTsPPlirX1sbHXZyQSA5yAAokSPPvqoTJ8+XT766COJjY3VkzvUEjD33Xefvn777bfrFjwHNUFEBb6XX35Zdu7cqc+//PKLXkoGuBTpVm+97ZuXReSOvud2yVDDC6I7RMktk66XN1a+IF8f+0DCGtUxrlZQ9lKjYBNwhVGofDPWHpK0rDxpVq8mCz8DcDkCIEqklnVRM3iff/556dy5syxfvlzmzZsnUVFR+roKg8eO2XdjUFRL31dffSUff/yxdOzYUU8IUWsJquVkgEtxRAL0eXj7hqVu+1a7foi0v6yN8apirNm/2gvetu9z7+b2ciXLySs426J574BmevkaAHAlZgHDrTDbDYVNeWe+/LRql5xo3EKsYpHZ9/eVblG1jauVz1qQKdbEnrZSjkjgneIV/JT9QiWbtfGwPPbNFqkX5C+/PXGF+Pt4G1eAC/FchDPQAgjArWUG1dbhr3NkqFPDn5azSv1HF501/k9t+/b+8r26/Kd+0YQ/AFWCAAjAbeVZrZJZyz479k+XOX+ixNnuX0uwiF9Xe7mSLdmVKLuPp+vZzON7NzFqAcC1CIAA3Nb+DJECbx/xk3wZ3j7cqHUOq7VAJHuJ/YX/5WKx+NrLley9Zfv0eXyvJhIc4Jw/AwAuhgAIwC2p4cl/pNmHKDeSLPH1dvLjKnerLW2e1EWLv3Nm/248eFrWHThl+1osclc/ln4BUHUIgADc0gZbWDqVaysUFEi4FL+VYGU62/0rPiL+A4xy5Zq2NE6fR3VuJOEh9pnNAFAVCIAA3JLaJUOpkZkqvhYXLFbg6P716y4Wr8qfabkzIVV+iU0UtTPifQOds7wMAJQVARCA2zmWckYWbLdvK1gz7bQ+O5M177BI3i5dtvhfqc+VbdpS+8zfEe0bSvN6ztteDgDKggAIwO18seaQ5BdYJdxfxDfX+d2/crb718YJAfDgyQz5YctRXb6f1j8AboAACMCtZOXmy4x1h3S5TZBrdsg4O/7Pp4VYfCp/aZZ3l+0TW56Vga3rSftGIUYtAFQdAiAAt/Lj1mNyMiNHIkICpEkNo9KJrAVpIjnr7S+c0Pp3PDVLZm88rMsPXNFCnwGgqhEAAbiV/622T/4Y3ztKvNSMCWfLXmH7j5pu7Jzxf9NX7JOc/ALp0bS27ahj1AJA1SIAAnAbW+KTZevhFPHz9pKxPSKNWuc62/3rZQtnvp3s5UpyKiNHvlhr787+K61/ANwIARCA2/h8zUF9vrpjQ6lby1+XnclqzRPJXmZ/4T9QLJbK3Zf3o9/2S2ZOvrSLCJaBreoZtQBQ9QiAANxCcmaOzDVmyt7aO0qfnS53ky0FpuhiZXf/pmTmnl3L8MErW9rCpWsmtABAWRAAAbiFWRsPS3ZegbRtGCxdm4Qatc5lzVpslHxF/PoZ5crx8ar9kp6dJzHhQTKkbQOjFgDcAwEQQJUrKLCe7f5VrX8uay07u/tHb7F41bSXK0FaVq7u/lUmXNlCvLxo/QPgXgiAAKrcb3FJcuBkpgT5+8h1nSOMWuey5u0TybeHNEvAVfpcWf63+qCkZuVJ83o1ZXj7hkYtALgPAiCAKveZ0fp3Q7fGUtMWAl3C0fqn+F9hFC5dRnaeXvpFUWP/vGn9A+CGCIAAqlRCSpYsjj2uy+N7Vf4uHCWxZjl2/2grFu/Ka6VTXdmnM3Olad1AGdmR1j8A7okACKBKzdwQr7dJ69m0jrRsEGTUOpe14LRI7kb7i0ps/cvMyZP3l9tb/9S6fz7ePGIBuCeeTgCqTL4t+X29Pl6Xb+nlmoWftezltv8U6GJljv9TY//UNnZN6gTK9V0aGbUA4H4IgACqzPI9J+RI8hkJqeHr0skS53b/qC/i085evkRq7J+j9e+hq1qKL61/ANwYTygAVWaGsU3a6K6NJMC3cnfhKInVmmO0ANr4X1lpS858uvqA3votOqymjHLRTGYAqCgCIIAqcTw1SxbvTNTlcT1dN/lDctbbUmCGLloqafyfWvDZ0fr34JWM/QPg/nhKAagS32yI12MAezSt7bLJH8rZ7l9LDRH/PvbyJfp01QFJzsyVZmE15dpOtP4BcH8EQAAup3b++Mox+cOFrX9Wq1XEsfyLX1+xWALs5UuQmpV73tg/Wv8AeAKeVABcbvW+k3L49BkJCvCRER1cuFZe3m5b+jyiixb/K/X5Un2y8oCknMnVu35cQ+sfAA9BAATgco6lX9S2b66a/KE5un/FUinr/yVn5sgHRuvfw4NasesHAI9BAATgUimZubJgR4Iu39TdhWv/2Zwd/+fbUSzeYfbyJXjPFv7SsvMkJjxIRrqyJRMALhEBEIBLzd1yRHLyCnRo6tAoxKh1Pmv+CZHcrbpcGd2/iWlZuvtX+duQ1uJF6x8AD0IABOBSX2+wd/+q1r/KWoOvTLKX2v5jtZcrIQC+s2SvnMnNl06RoTKoTX2jFgA8AwEQgMvsOJoi24+kiq+3RUa5eKu0s92/3o1FfFrZyxV0NPmMfGksYv33Ia1dG2QBoBIQAAG4zDcbDuvzkLbhUqemny67gtWaJZK90v7C/4pLDmxv/rpHcvILpHezOtKvRV2jFgA8BwEQgEuocX/fb7YvwXJj98b67DLZq23/sYVAm0sd/3cgKUNmGkH2MVr/AHgoAiAAl1i6K1FOZ+ZKvSB/6d/i0mfglse53T9qifj1sJcr6N+LdusdTAa2rifdm9YxagHAsxAAAbjEt7/bW/+u79LIpbtlWK0FItlL7C/8+4vFUvGu5+1HUuSHLUdtn0Pk8aExRi0AeB4CIACnO52RI4t3Htfl0V1dO/lD8naIFCTq4qV2/768YKc+X9cpQtpGBOsyAHgiAiAAp/tx61HJzbdK24bBEhPu2uBkdez9qx53/gOMcvmtikuSFXuS9AzmRwe3NmoBwDMRAAE43Wyj+9flrX/K2d0/uonFq7a9XE5Wq/Vs69+4nk2kSd1AXQYAT0UABOBUe0+ky+b4ZL1P7nWdXbz2X/4xkbxYXbYEVLz7d/72BNlyOEUC/bxlwpUtjVoA8FwEQABO9d0me+vfgJZhegawSzkmfygVHP+Xl18g//fzLl2+u38z138NAOAEBEAATqO6Tr/ffFSXXb3zh2LNWmwveEeLxSfaXi6nr9bHy76kDL1w9T39K/Y5AMDdEAABOI3q+j10KlN3nQ5u28CodQ1rQYZIzhr7iwq2/qVn58nrv+zW5YevailBAb66DACejgAIwGkcrX9DbOEv0M9Hl10m5zfbf3J1saLj/95btleS0nOkad1AuaVnE6MWADwfARCAU6ixc2r5F8XVkz8Uq2P8nyVUxLeLvVwOCSlZ8sGKfbr8xLAY8fPhcQmg+uCJBsApVu09qVvP1Ni5y1q6eOs3a75IlmP3jwFisZS/9fG1RbskK7dAukXVlmHtw41aAKgeCIAAnMLR/Xt1h4bi68Kt37TcLbYUeFoXLQFX6XN57ExIlW82Htblp0bE2AKkRZcBoLogAAKodFm5+bJwR4IuX9s5Qp9dyZptzP4VXxG//ka57KbO2ylWq8jw9uHSLaqOUQsA1QcBEEClU1umpWXnSXhwgHRrUrHdNy6JY/yfXw+xeNWyl8to2e4T+vDxssjjw2KMWgCoXgiAACrdT8bkjxEdGoqXLUi5kjXvkEhenC5byrn8i5q48q8f/9Dl2/s0leiwmroMANUNARBApVLdv7/EJury1R0b6rNLOfb+VcoZAGesj5c9iekSGuir1/0DgOqKAAigUi3ffUIvoBwREiBdIkONWtexOgKgT2ux+DS2l8sg5Uyu/GeRfdHnRwa1khBbCASA6ooACKBS/bTtmD5XSfdvQapIzgb7C/8r7OcyeuvXPXIqI0da1K8l43qx6DOA6o0ACKDS6O7fP47rctV0/y63/SdPFy3+ZV/+5UBShnyy6oAuP311G9cvWwMALsZTDkClUbN/M3Lydfdv56rs/vUKE/HtYC+XwYvzYiU33yqXt6onV7Sub9QCQPVFAARQaX421v4b0i7c5YsnW625Rgugjf9A259ftsfbij0nZOEfx8XbyyL/uLqNUQsA1RsBEEClUEuo/BJr7/4daguALpez0ZYCU3WxrMu/5Nr+zlN+cCz7EiUtGwTpMgBUdwRAFOv06dNy2223SUhIiD5UOTk52bhavIEDVauL5bxj7NixxlVUd+v2n5LkzFy992+Ppq5f/Pls96/4i/j1Ncql+9/qgxKXmK7/zhMHtTJqAaD6IwCiWOPGjZPNmzfLggUL9KHKKgRezD333CPHjh07e7z33nvGFVR3ju7fQW3qi4+LJ1FY1b5tjgDo30csXoH2cimS0rPldWPZl8eHtpaQGiz7AsA8CIC4QGxsrA5906dPlz59+ujjgw8+kB9//FF27dpl3FW8wMBACQ8PP3uo1kNUfwUFVlsArMLu3/y9tuOQLpa1+/eVBTv1dnUdGoXImO6RRi0AmAMBEBdYvXq1Dm69evUyakR69+6t61atWmXUFO+LL76QsLAwadeunTz22GOSlpZmXEF1tu1IiiSkZklNP2/p1yLMqHWhrMK7fww0CiXbHJ8sMzcc1uXJ17bTE0AAwEwIgLhAQkKC1K9/4VIYqk5dK8n48eNlxowZsnTpUnnmmWdk9uzZMnr0aONq8bKzsyU1NfW8A55n8U771m8DWtWTAF9vXXalc7t/tBeLd+ktkKq18rm5O3R5dNdG0i3K9eMVAaCqEQBNZPLkyRdM0ih6bNhg30VBlYtS46yKq3dQ4/8GDRok7du315M/Zs2aJb/88ov8/vvvxh0Xmjp16tmJJuqIjKQrzhP9utPe/XtVmwb67ErWglMiuZt12RJw8e7fr9bHy5b4ZKnl7yNPDosxagHAXAiAJjJhwgQ9vq+0Q4U3NXbv+HH7D/TCTpw4IQ0alP0HfNeuXcXX11f27Nlj1Fxo0qRJkpKScvaIj483rsBTJKRkyfYjqbZfDkQGtq5n1LpQ9lLbfwrs5YuM/zuZni0vL9ipy48ObiX1gwN0GQDMhgBoImpsXkxMTKlHQECAnvShwti6deuMjxRZu3atruvbt2zLayg7duyQ3Nxcadiw5C3B/P39JTg4+LwDnuVXo/tX7fwRVstfl13JmrXEXvAKF/EpfSFnFf5SzuRKm4bBet0/ADArAiAu0KZNGxk2bJju0l2zZo0+VHnkyJHSunVrfc+RI0d0YHSExL1798rzzz+vu5APHDgg8+bNkzFjxkiXLl2kX79++h5UT2e7f2Ncv4Wa1ZojkvOb/YX/laUOUdh48NTZiR//GtXO5UvVAIA74QmIYqnZvB06dJAhQ4boo2PHjvLZZ58ZV0W37KklYTIzM/VrPz8/Wbx4sQwdOlSHxIceekh/nBoD6O3t+kkBcI2s3Hz5LS5Jl6+Mcf34P8lZa0uBGbpY2vg/tUvJP76zT/y4qXtj6RZVR5cBwKwIgChWnTp15PPPPz87M1eVQ0PPbe7ftGlTPSlE7f6hqMkby5Ytk5MnT+qZvXFxcfLGG2/oz4PqS+3+kZVbIOHBAdKmoeu3UbNmL7YXLIG230LOLVtU1KerD0rssVS92PMTTPwAAAIggIpbvvuEPg9oFVZq96sz6N0/HOP//C6z/fnFjz88knxG/r3QvoC5Cn91q2CcIgC4GwIggApbvsceAPu3rILZv3mxIgXHdLGk3T9USHzu++2SmZMv3aNqy9geLDMEAAoBEECFqOVfdh9P18u/XFYVu39kG61/YvsL+F9ulM+n9if+JTZRfL0t8uLoDuLFjh8AoBEAAVSIo/WvY+NQqV3TT5ddyZpljP/z7SIW77r2ciGpWblnd/y4d0BzadXA9WMUAcBdEQABVMiKPfbZvwNaur71z5p/XCRvuy5b/K/Q56L+7+ddcjw1W5rWDZQJV7YwagEACgEQQLmpsXWr99oDYNV0/6rdPwwBVxmFczYePC2frTmoyy9c36FK9icGAHdGAARQbnGJ6ZKUniP+Pl7Sucm55YFcxZr9q73gHWk7mtvLhuy8fHli9lZbSBUZ3bWR9KuKgAoAbo4ACKDcVu87qc/dm9a2hUDXtq5ZrWdsKW+V/YX/VRcsP/Pm4jgdUNW2dM+ObGvUAgAKIwACKLc1RgDsHX3h5Aun0+EvWxeLjv/bcTRFpi3bq8v/vK6dhAa6fnIKAHgCAiCAcikosNoC4Cld7tPc9QHwbPevJUjEr7u9bJObXyCPz9oq+ba/34gO4TK8Q0PjCgCgKAIggHKJO5EupzJyJMDXSy8B40pWa4GcXf/Pf4BYLL72ss37y/fJjqOpEhroK1OubW/UAgCKQwAEUC4bDpzW5y6RtcXPx8WPkNxtIgX22ccW/3Ozf3cfT5M3ftmjy2rcX70gtnsDgNIQAAGUy++H7AGwW1RtfXals92/4i3i31+XVNfvozM3S47tfFVMfbm+SyNdDwAoGQEQQLn8ftAeALtGuab7t35ouljEan/hCIB+PcTiFaKLb/0aJ9uP2Lt+p97Q4YJZwQCACxEAAZSZGvu3LylDl1UXsDPkFxTIqx//IgeO2Gca92h1WO4Z8r2cPrVTJG+XrnPM/t12OEXeWhKny/8a1V7qBwXoMgCgdARAAGW2yej+bVavptP2//X28pLUtCwZ9/gnsnLTPlENen3bbJecE7cYd9j4Xy5ZZ+Lk0Znr9KzfkR0b2o4I4yIA4GIIgADKbMvhFH3uHOnc7t/LujbXO3mkZWSd7f6tF2JveVSsSdfKqz9Mlz2JOXrB539ex6xfACgPAiCAMvvjqD0AdmhkH3/nLL07NxVvr5LH8q042FQ+/N0+CeTlGzo4rTUSAKorAiCAMlOTLZT2Tg6AIbVqSIdWxmzeIjnw1Jma8veFd+jyrb2byFVtGugyAKDsCIAAyiQpPVsSUrP0mLw2DYONWufp16WZPp+dAWyjuoUnLbpFEjMCpUX9WvL0CPb6BYCKIAACKBO1y4YSHVZTavn76LIzXdbVHgAL+3p7b1m0r534elvkjbGdpYaft3EFAFAeBEAAZbI7IU2f24Q7v/VPiYqoI40bhOoWR2XPyQbyz+U36PLjQ2OkXYRzu6EBoDojAAIok7jEdH1WXa+uoBZ0VrOBlTO5vvLgvDttZx/p3zJM/nxZtK4HAFQMARBAmcSdsAfA5i4KgIrqBlYNgJOXjpbdJ8P1Hr+v3dRZvEqZIQwAuDgCIICLslqt51oA67kuAHZq3Uj25UTJNzt6i8p8atyfCoEAgEtDAARwUWoLuJQzuXo8npoE4ioHTmXK0lOddfnhq1pJ3+ZhugwAuDQEQAAXdST5jD7XD/J32czbtKxc+ctnGyU731v6tagrE65sYVwBAFwqAiCAizpqBMCI0Br67GwFBVb528wtsu9EhjQMCZA3xnYpdWcQAED5EAABXNTR5Cx9jghxTQCctmyvLPzjuPh5e8m0W7vp/X4BAJWHAAjgohwtgKo1ztmW7kqU/1u4S5efv66ddI4M1WUAQOUhAAK4KDUJRHH2DNw9x9PkwS836S3fbunZRMbaDgBA5SMAArio1KxcfQ6p4avPznAyPVv+9Ol6ScvOkx5Na8vka9nnFwCchQAI4KLUEjBKsJMCYHZevtz72UaJP3VGmtQJlPdu6y7+PuzzCwDOQgAEcFFpWXn6HBxQ+QFQzfh9YtZW2XDwtAQF+MhHd3aXOjX9jKsAAGcgAAK4qHxbSFOcsRTL1Pmx8t3mo/pzvzO+q7SoH2RcAQA4CwEQQJV5b9le+WDFfl1+5YaO0r9lPV0GADgXARBAlfhmQ7xMnb9Tl58aESM3dGusywAA5yMAArioAF/7hIwzufaxgJdqzqbD8sTsrbr8lwHNbEdzXQYAuAYBEMBF1a1ln5SRlG5fD/BSqPCntnlTwwrVWn9PDosxrgAAXIUACOCiHLNyk9Kz9bmiZm08P/y9MKq9eLHHLwC4HAEQwEVF1ampz3HH0/W5vKxWq7yzNE4e+4bwBwDugAAI4KI6NA7W561HUvS5PNQSMpPn7pBXFtj39713QDPCHwBUMQIggIvq0ChUn/eeSJcjyWd0uSxUl/FtH66VT1cfFIst7z07sq1MGtGG8AcAVYwACOCi6gX5S6/oOmK1isz5/bBRW7o1+07K1f9dIav2npRAP295e1xX+dNl0cZVAEBVIgACKJMx3SP1+f3l+yQxLUuXi5OcmSNPzt4qY99fI8dTs6VF/Voyd0I/GdGhoXEHAKCqEQABlMmozhHSoVGIpGblyT2fbpDE1PNDoAqF/164Swb+31L5an28rhvbI1K+f6Af27sBgJuxWNX0PMBNpKamSkhIiKSkpEhwsH3iAdzHroQ0ufn91ZKcmSt+3l7Su3ldCfL3kX1JGbIzIVV3ESst69eSF0d3kB5N69grAFQYz0U4AwEQboUHnfvbbwt7D3+1SbYevnBGcNcmoXJP/2YypF24eDPRA6gUPBfhDARAuBUedJ5BPTb+OJYqm+OTJSevQOoHBUiP6Nr6DKBy8VyEMxAA4VZ40AHA+XguwhmYBAIAAGAyBEAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAFGsF154Qfr27SuBgYESGhpq1JZOLSk5efJkiYiIkBo1asjAgQNlx44dxlUAAOAuCIAoVk5OjowZM0buv/9+o+biXnnlFXnttdfkrbfekvXr10t4eLgMHjxY0tLSjDsAAIA7IACiWFOmTJFHHnlEOnToYNSUTrX+vf766/L000/L6NGjpX379vLpp59KZmamfPnll8ZdAADAHRAAUSn2798vCQkJMmTIEKNGxN/fXy6//HJZtWqVUQMAANwBARCVQoU/pUGDBvrsoF47rhUnOztb73NZ+AAAAM5FADQRNUHDYrGUemzYsMG4u2LU5yhMdQ0XrSts6tSpepNzxxEZGWlcAQAAzkIANJEJEyZIbGxsqYcau1cRasKHUrS1LzEx8YJWwcImTZokKSkpZ4/4+HjjCgAAcBYCoImEhYVJTExMqUdAQIBxd/lER0frELho0SKjxj6TeNmyZXo5mZKocYLBwcHnHQAAwLkIgCjWoUOHZPPmzfqcn5+vy+pIT0837hAdGOfMmaPLqpt34sSJ8uKLL+q67du3y5133qnXERw3bpy+BwAAuAcCIIr17LPPSpcuXeS5557ToU+V1VF4jOCuXbt0t63D448/rkPgX//6V+nevbscOXJEFi5cKEFBQcYdAADAHVisapQ+4CbULGA1GUQFS7qDAYDnIpyDFkAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAAEAAEyGAAgAAGAyBEAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAAEAAEyGAAgAAGAyBEAAAACTIQACAACYDAEQAADAZAiAAAAAJmOx2hhloMqlpKRIaGioxMfHS3BwsFELAOaVmpoqkZGRkpycLCEhIUYtcGkIgHArhw8f1g86AMD51C/GjRs3Nl4Bl4YACLdSUFAgR48elaCgILFYLEatczh+q6a10Y7343y8H+fj/TifK98P9WM6LS1NIiIixMuLkVuoHARAmJZ6gKvuFNXtzA803o+ieD/Ox/txPt4PeDp+lQAAADAZAiAAAIDJeE+2McqA6Xh7e8vAgQPFx8fHqDE33o/z8X6cj/fjfLwf8GSMAQQAADAZuoABAABMhgAIAABgMgRAAAAAkyEAAgAAmAwBEKbywgsvSN++fSUwMFDvOVwWap6UmiyvVuGvUaOGnvW3Y8cO46pnO336tNx22216QVt1qLLab7Q06utXu7QUPsaOHWtc9SzvvPOOREdHS0BAgHTr1k1WrFhhXCne7NmzpW3btuLv76/Pc+bMMa5UD+V5Pz755JMLvg/UkZWVZdzh2ZYvXy7XXHON/nevvq7vvvvOuFKyZcuW6fdNvX/NmjWTd99917gCuB8CIEwlJydHxowZI/fff79Rc3GvvPKKvPbaa/LWW2/J+vXrJTw8XAYPHqy3ZvJ048aNk82bN8uCBQv0ocoqBF7MPffcI8eOHTt7vPfee8YVz/H111/LxIkT5emnn5ZNmzZJ//79Zfjw4XLo0CHjjvOtXr1abr75Zv3+bNmyRZ9vuukmWbt2rXGHZyvv+6GoHTAKfx+oQ4Wf6iAjI0M6deqk/92Xxf79+2XEiBH6fVPv31NPPSUPPfSQ/qUBcEtqGRjAbD7++GNrSEiI8apkBQUFVlvgs7700ktGjdWalZWlP9b2271R45n++OMPtQSUdc2aNUaN1WoLObpu586dRs2FLr/8cuvDDz9svPJcPXv2tN53333GK7uYmBjrk08+abw6ny3sWYcNG2a8shs6dKh17NixxivPVt73o6z/hqoD9W9izpw5xqviPf744/r9Kuzee++19u7d23gFuBdaAIFSqN/qExISZMiQIUaN6O4/WwiSVatWGTWeSbVoqW7fXr16GTUith9Wuu5iX9sXX3whYWFh0q5dO3nsscc8rjVUtQRv3LjxvP+vinpd0teu3q+i99sCoMd/HygVeT+U9PR0iYqKksaNG8vIkSN1y5dZlfT9sWHDBsnNzTVqAPdBAARKocKf0qBBA312UK8d1zyV+vvXr1/feHWOqivtaxs/frzMmDFDli5dKs8884zu4ho9erRx1TMkJSVJfn5+uf6/qvrq+H2gVOT9iImJ0eMA586dq78fVNdvv379ZM+ePcYd5lLS90deXp5+fwF3QwCEx1MTNIoORC96qN/CL4X6HIVZrdYL6txFed4PVS7qYl+bGv83aNAgad++vZ78MWvWLPnll1/k999/N+7wHEW/zot97eW939OU5+tTrcW33nqrHienxr3NnDlTWrVqJW+++aZxh/kU9/4p1el7BNUHARAeb8KECRIbG1vqocJKRagJH0rRVpDExMQLftt3F2V9P9TXdvz4ceOjzjlx4kS5vrauXbuKr6+vR7X8qO5rtY9ref6/qvfLk74PyqMi70dRXl5e0qNHD9O2AJb0/aH2Ca5bt65RA7gPAiA8nvrhpbqjSjsqOjNRLYmhHuyLFi0yauzjpdRyD2o5GXdU1vejT58+kpKSIuvWrTM+UvSMVlVXnq9NLYmjxjg1bNjQqHF/fn5+ermOwv9fFfW6pK9dvV9F71+4cKHbfh+UR0Xej6JUa5eaRe5J3weVqaTvj+7du+tfkAC3Y/tHC5jGwYMHrZs2bbJOmTLFWqtWLV1WR1pamnGH1dq6dWvrt99+a7yy6hnAarajqtu2bZv1lltusdp+yFlTU1ONOzyXmtXasWNHPftXHR06dLCOHDnSuGq1Hj58WL8ftmCoX8fFxen3bv369db9+/dbf/rpJz3zsUuXLta8vDx9j6f46quvrLYfzNYPP/xQz4ieOHGitWbNmtYDBw7o67fddtt5M2BXrlxp9fb21t8PsbGx+uzj43PeLGpPVt73Y/LkydYFCxZY9+7dq/8N3XXXXfr9cHyveDr1THA8H9SPytdee02X1TNEUe+Fek8c9u3bZw0MDLQ+8sgj+v1T76N6P2fNmmXcAbgXAiBM5Y477tAP86LHkiVLjDv0oB29xIWDWgrmueee08vB+Pv7WwcMGKCDYHVw8uRJ6/jx461BQUH6UOXTp08bV6065BV+fw4dOqS//jp16lj9/PyszZs3tz700EP683iit99+2xoVFaW/lq5du1qXLVtmXLEvd6O+Xwr75ptvdCBWP9hV8J09e7ZxpXooz/uhAmKTJk30vfXq1bMOGTLEumrVKuOq51Pf84WfEY7D8R6os3pPClu6dKn+ZUi9J02bNrVOmzbNuAK4H4v6j+2bGgAAACbBGEAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAAEAAEyGAAgAAGAyBEAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAAEAAEyGAAgAAGAyBEAAAACTIQACAACYDAEQAADAZAiAAAAAJkMABAAAMBkCIAAAgMkQAAEAAEyGAAgAAGAyBEAAAACTsVhtjDIAAPAwBQUFcvToUQkKChKLxWLUmoeKMWlpaRIRESFeXrRrlRUBEAAAD3b48GGJjIw0XplXfHy8NG7c2HiFiyEAAgDgwVJSUiQ0NFSWLVsmtWrVMmrNIz09XS6//HJJTk6WkJAQoxYXQwAEAMCDpaam6uCzceNG0wbAbt266SAcHBxs1OJi6CwHAAAwGQIgAACAyRAAAQAATIYACAAAYDIEQAAAAJMhAAIAAJgMy8BUE2ZfCR6AeakfY2beCYJlYFgGpiIIgJXowIEDEh0dLZs2bZLOnTsbta7BSvAAzM6sO0G4MgCuXbtWbr/9dlm/fr3bhC0CYMUQAMvoYq1qd9xxh3z44Ydy4sQJCQsLEx8fH+OKazhWgr/ixskS17itUQtc3PYpQ40S4JlUAFK/AJe2E8TUqVPl22+/lZ07d0qNGjWkb9++8vLLL0vr1q2NOy40cOBAvbtGUSNGjJCffvpJl48fPy5PPPGELFy4UP/5AwYMkDfffFNatmypr7tCZQfAJ598UubMmaPL6mdZeHi4DBkyRB588EHZtm0bAbCaIACWUUJCglES+frrr+XZZ5+VXbt2GTWiHyglPXhcwfEAGHzLS7K7SXujFri4Ay9dbZQAz+R4/pUWAIYNGyZjx46VHj16SF5enjz99NM6zPzxxx9Ss2ZN467znTp1SnJycoxXIidPnpROnTrJ9OnT5c4779RdzypI+vr6yr///W/9Z7/22muyYMGCUj9vZXNGAExKStKhWb1XGzZskH/84x8yatQoHX4JgNUDk0DKSP0G5DjUPzTVIli0TnUBq/rNmzfrj1m6dKl+/fPPP0uXLl10SLzyyislMTFR5s+fL23atNHfrLfccotkZmbqj1HUQ+WVV16RZs2a6Y9RD5xZs2YZVwEA5aVCmQpt7dq108/Ujz/+WA4dOqRDU0nq1Klz3nN+0aJFEhgYKGPGjNHX9+zZI2vWrJFp06bpYKlaE9955x0dSGbMmKHvUdTPARUar7/+ev3xqnVw7ty5xlWR06dPy/jx46VevXr6ma+uq79fVfLz89N/n4YNG8o111yjj8WLFxtXz1F/90cffVS3fKr3Vd33448/GldFvvvuO+nVq9d5QVpRrYmPP/648QpVgQDoApMnT5a33npLVq1apceo3HTTTfL666/Ll19+qbsR1ENFdRk4qN+01D9+9VDZsWOHPPLII3LrrbcW2xUBACg/1VqkqJBXVmqYj2pFdLTsZWdn63NAQIA+K97e3jo8/fbbb0aN3ZQpU/Szf+vWrboVTQU+1cKoPPPMM7rFUDUMxMbG6me/GkrkTtTXmJuba7w6RwU7Farfe+89HfzU16iC3ZYtW/R11fKan59/XnhUX/eSJUtk9OjRRg2qAgHQBf71r39Jv379dCvgn//8Zx3k1D9w9bp///5y44036n8MSkZGhu5C+Oijj2To0KG6FVD91qoCoPoHBgC4NKqXRbVaXXbZZdK+fdmGzKxbt062b98ud999t1EjEhMTI1FRUTJp0iTdEqbC0EsvvaSHDB07dsy4y049x1VvT4sWLeTFF1/Uz3r1ORXVEql+HnTv3l2aNm0qgwYN0i1p7kKF1h9++EH69Olj1JzToEED/XNN9WipcZi33Xabfl9Vi6uiguPIkSP1+EsH9blUi6pqGUTVIQC6QMeOHY2S/R+L6gJQwc5B1aluYUX9FpiVlSWDBw/WYzkcx//+9z/Zu3evvgcAUHETJkzQoaZwN+3FqNY/FRZ79uxp1Ige+zd79mzZvXu3bklUz3Y19Gf48OG6JbCwwj8HVAuiWrLL8dy///775auvvtKrR6jWM9VbVNXU16FCaYcOHeTmm2/WXdyqpbIo1bqnGjRUYFWBTn3MypUr9bJkDqpVUNWpCTOKCoOqO/xikyvhXARAF1APCQf1DV/4taLq1Dp+iuOsuobVWELHoYIh4wAB4NKosWdq/J3qdSnrkjFqjLYKaIVb/xzU5AP1jFYzgFWrn2r5UpNF1JJghZX23FeB8eDBgzJx4kQdnK666ip57LHH9LWqosKcGr+nvh4VltUwprp16xpXz1G9VZ988ol+bz799FP9MaoFsHB3cdu2bXVrqbqmhjWpwEz3b9UjALoZ9Q/F399fdwmoroLCB+v8AUDFqG5f1fKnWp9+/fXXCwJaaWbOnKnH+6mhOCVREwHVpAk1MUTNmr3uuuuMK2WjPlZ1E3/++ed6jPj7779vXKkaajKK6t5u1KjRBeG1MDWJRgVW9fWqkKd+TqkJkUWpoU7qvVctpmrmtJpcgqpFAHQzqltA/eanJn6o36ZUt69aWPrtt9/WrwEA5ffAAw/ocKUm36nnrBqnp44zZ84Yd4he3kSN5ytKdf+qJVCKawH75ptvdHfpvn375Pvvv9fDd9S9at28slLLiqmPjYuL0y1kajKFGlPnCZo0aaK7rH///Xf980p9LWoJmaKuvfZa3QWswvQNN9xg1KIqEQDd0D//+U/9j0itwaQeAmoyiBo0W57fWAEA56hxamrmr1rcWbU+OQ61rquD6nkpOnlDdVeqGb1qokNx1P1q4oNq/XrooYd0uTxjCxU1a1gFTzVOUC2nosYPqi5nT/DXv/5V91yp90d97Wr2sprEUpQay65CsRr/WNx1uB4LQVcTLASNimIhaHi6siwEXZ1V9kLQznLXXXdJ8+bN9VJnlYmFoCuGFkAAAOA0aoKMmtioFs0eN26cUYuqRgtgNaF+82EvYFQEewHD06kWsIvtBVyduXsLoNoBS/2MUt3FJXWlXwpaACuGAFhNHD58mFnCAExN7bRU1qVdqhNP6QJ2FgJgxRAAqwm1npRaP0rNbmNxTQBmon6MpaWlSUREhHh5mW9kEwGQAFgRBEAAADwYAZAAWBFMAgEAADAZAiAAAIDJEAABAABMhgAIAABgMgRAAAAAkyEAAgAAmAzLwAAA4MHU8idqJ6hly5aZdhmYyy+/3LQ7wVQUARAAAA/GTlB2Zt0JpqIIgAAAeDCz7wSlYoyZd4KpKAIgAACAyRCVAQAATIYACAAAYDIEQAAAAJMhAAIAAJgMARAAAMBkCIAAAAAmQwAEAAAwGQIgAACAyRAAAQAATIYACAAAYDIEQAAAAFMR+X/xOoB4O9FMywAAAABJRU5ErkJggg==" width="640">”

], “text/plain”: [

“<IPython.core.display.HTML object>”

]

}, “metadata”: {}, “output_type”: “display_data”

}

], “source”: [

“fig, ax = plt.subplots()n”, “n”, “n”, “def animate(i):n”, “ ax.set_title("Polarization")n”, “ ax.set_aspect("equal")n”, “ ax.set(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2))n”, “n”, “ E = E0 * np.exp(1j * (f * t[i] + phi))n”, “n”, “ xx = np.array([0, E[0].real, 0])n”, “ yy = np.array([0, 0, 0])n”, “ uu = np.array([E[0].real, 0, E[0].real])n”, “ vv = np.array([0, E[1].real, E[1].real])n”, “n”, “ plax = ax.plot(ES[0].real, ES.real[1])n”, “ qax = ax.quiver(xx, yy, uu, vv, [0, 55, 200], scale_units="xy", scale=1.0)n”, “n”, “n”, “animate(0) # initialise the plot with the animate functionn”, “n”, “timeline = amp.Timeline(t, units="ns", fps=10)n”, “block = amp.blocks.Nuke(animate, length=len(timeline), ax=ax)n”, “anim = amp.Animation([block], timeline)n”, “n”, “anim.controls()n”, “anim.save_gif("nuke")n”, “plt.show()”

]

}, {

“cell_type”: “raw”, “metadata”: {

“raw_mimetype”: “text/restructuredtext”

}, “source”: [

“.. image:: nuke.gif”

]

}

], “metadata”: {

“celltoolbar”: “Raw Cell Format”, “kernelspec”: {

“display_name”: “Python 3”, “language”: “python”, “name”: “python3”

}, “language_info”: {

“codemirror_mode”: {

“name”: “ipython”, “version”: 3

}, “file_extension”: “.py”, “mimetype”: “text/x-python”, “name”: “python”, “nbconvert_exporter”: “python”, “pygments_lexer”: “ipython3”, “version”: “3.6.5”

}

}, “nbformat”: 4, “nbformat_minor”: 2

}